JavaIO流——合併流/順序流(SequenceInputStream):,就是把多個輸入流,合併成一個流對象,且見代碼1。
代碼1——合併流:
package mypackage;import java.io.FileInputStream;import java.io.SequenceInputStream;//合併流/順序流(SequenceInputStream):// 就是把多個輸入流,合併成一個流對象.public class Test { public static void main(String[] args) throws Exception { // 不同輸入流有不同對應txt文件,將輸入流合併後,合併後的輸入流可以操作多個文件 SequenceInputStream sequenceInputStream = new SequenceInputStream( new FileInputStream("stream1.txt"), new FileInputStream("stream2.txt")); byte[] buffer = new byte[1024]; int len = -1; while ((len = sequenceInputStream.read(buffer)) != -1) { System.out.println(new String(buffer, 0, len)); } sequenceInputStream.close(); }}
輸出1:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結1:
1、合併流對應的對象是輸入流,是對輸入流合併,不是對輸出流合併;
2、合併的是兩個輸入流而不是兩個源文件:因為不同輸入流有不同對應txt文件,用合併流將兩個輸入流合併後,可以輸入兩個文件,所以說,合併的是兩個輸入流而不是兩個源文件。
3、合併流可以接收合併流作為實際參數,形成多個流的合併,也稱合併嵌套。
合併流定義:JavaIO流——合併流,接收兩個輸入流作為參數,合併兩個輸入流或合併流,對外形成一個更大的流,方便客戶端操作。
合併流需要注意的點:
1、合併流對應的對象是輸入流,是對輸入流合併,不是對輸出流合併;
2、因為不同輸入流有不同對應txt文件,用合併流將兩個輸入流合併後,可以輸入兩個文件,注意合併的是兩個輸入流而不是兩個源文件。
3、合併流可以接收合併流作為實際參數,形成多個流的合併,也稱合併嵌套。
1.1 序列化和反序列化定義:
序列化: 指把堆內存中的Java對象數據,通過某種方式把對象存儲到磁碟文件中或者傳遞給其他網絡的節點(在網絡上傳輸). 我們把這個過程稱之為序列化.
反序列化:把磁碟文件中的對象數據或者把網絡節點上的對象數據,恢復成Java對象的過程.
1.2 為什麼要做序列化:
1):在分布式系統中,需要共享的數據的JavaBean對象,都得做序列化,此時需要把對象再網絡上傳輸,此時就得把對象數據轉換為二進位形式.以後存儲在HttpSession中的對象,都應該實現序列化接口(只有實現序列化接口的類,才能做序列化操作).
2):服務鈍化:如果服務發現某些對象好久都沒有活動了,此時伺服器就會把這些內存中的對象,持久化在本地磁碟文件中(Java對象–>二進位文件). 如果某些對象需要活動的時候,現在內存中去尋找,找到就使用,找不到再去磁碟文件中,反序列化我們得對象數據,恢復成Java對象.
1.3 Java對象流——JavaIO流中實現序列化的方式
使用對象流來完成序列化和反序列化操作:
ObjectOutputStream: 通過writeObject方法做序列化操作的.
ObjectInputStream: 通過readObject方法做反序列化操作的.
ObjectOutputStream ObjectInputStream,提供一種序列化方式,序列化方式有很多,現在網際網路大廠常用的是protobuf,最高效的系列化方式
代碼1:
package mypackage;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;//對象流 ObjectInputpublic class Test { public static void main(String[] args) throws Exception { File file = new File("object.txt"); writeObject(file); readObject(file); } private static void writeObject(File file) throws Exception { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); objectOutputStream.writeObject(new Person("小明", 12)); objectOutputStream.close(); } private static void readObject(File file) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); Person person = (Person) objectInputStream.readObject(); System.out.println(person); objectInputStream.close(); }}class Person { // 實體類沒有實現序列化接口Serializable private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; }}
輸出1:
Exception in thread "main" java.io.NotSerializableException: mypackage.Person at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) at mypackage.Test.writeObject(Test.java:20) at mypackage.Test.main(Test.java:14)
小結1:因為實體類Person沒有實現序列化接口Serializable,所以這裡程序拋出異常java.io.NotSerializableException
代碼2:
package mypackage1;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;//對象流 ObjectInputpublic class Test { public static void main(String[] args) throws Exception { File file = new File("object.txt"); writeObject(file); readObject(file); } private static void writeObject(File file) throws Exception { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); objectOutputStream.writeObject(new Person("小明", 12)); objectOutputStream.close(); } private static void readObject(File file) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); Person person = (Person) objectInputStream.readObject(); System.out.println(person); objectInputStream.close(); }}class Person implements Serializable { // 和代碼1的唯一不同,實體類實現Serializable接口 private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; }}
輸出2:
Person [name=小明, age=12]
小結2:實體類Person實現序列化接口後,成功解決了程序異常,一般來說,隨著項目的升級,系統的class文件也會升級(增加一個欄位/刪除一個欄位), Java通過serialVersionUID(序列化版本號)來判斷字節碼是否發生改變.所以我們為實體類Person添加一個序列化版本號。
代碼3:
package mypackage2;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;//對象流 ObjectInputpublic class Test { public static void main(String[] args) throws Exception { File file = new File("object.txt"); writeObject(file); readObject(file); } private static void writeObject(File file) throws Exception { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); objectOutputStream.writeObject(new Person("小明", 12)); objectOutputStream.close(); } private static void readObject(File file) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); Person person = (Person) objectInputStream.readObject(); System.out.println(person); objectInputStream.close(); }}class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; }}
輸出3:
Person [name=小明, age=12]
小結3:給實體類Person加上序列化版本號之後,整個問題正是解決。
1.1 序列化和反序列化定義:
序列化: 指把堆內存中的Java對象數據,通過某種方式把對象存儲到磁碟文件中或者傳遞給其他網絡的節點(在網絡上傳輸). 我們把這個過程稱之為序列化.
反序列化:把磁碟文件中的對象數據或者把網絡節點上的對象數據,恢復成Java對象的過程.
1.2 為什麼要做序列化:
1):在分布式系統中,需要共享的數據的JavaBean對象,都得做序列化,此時需要把對象再網絡上傳輸,此時就得把對象數據轉換為二進位形式.以後存儲在HttpSession中的對象,都應該實現序列化接口(只有實現序列化接口的類,才能做序列化操作).
2):服務鈍化:如果服務發現某些對象好久都沒有活動了,此時伺服器就會把這些內存中的對象,持久化在本地磁碟文件中(Java對象–>二進位文件). 如果某些對象需要活動的時候,現在內存中去尋找,找到就使用,找不到再去磁碟文件中,反序列化我們得對象數據,恢復成Java對象.
1.3 Java對象流——JavaIO流中實現序列化的方式
使用對象流來完成序列化和反序列化操作:
ObjectOutputStream: 通過writeObject方法做序列化操作的.
ObjectInputStream: 通過readObject方法做反序列化操作的.
ObjectOutputStream ObjectInputStream,提供一種序列化方式,序列化方式有很多,現在網際網路大廠常用的是protobuf,最高效的系列化方式
代碼1:因為實體類Person沒有實現序列化接口Serializable,所以這裡程序拋出異常java.io.NotSerializableException。
代碼2:實體類Person實現序列化接口後,成功解決了程序異常,一般來說,隨著項目的升級,系統的class文件也會升級(增加一個欄位/刪除一個欄位), Java通過serialVersionUID(序列化版本號)來判斷字節碼是否發生改變.所以我們為實體類Person添加一個序列化版本號。
代碼3:給實體類Person加上序列化版本號之後,整個問題正是解決。
JavaIO流——對象流通過writeObject()或readObject()實現序列化和反序列化,在磁碟讀寫和網絡請求中保證數據的正確性。
列印流定義:
列印到控制臺;解釋了System.out.println()底層原理,System.out.println();其實等價於 PrintStream ps = System.out; ps.println(),且見代碼1;
掃描流定義:
與列印流對應,解釋了控制到輸入底層原理,本質上是java.util.Scanner類:掃描器類,表示輸入操作,且見代碼2。
代碼1——列印流:
package mypackage_列印流;//System.out.println();其實等價於 PrintStream ps = System.out; ps.println()//Java public class Test { public static void main(String[] args) { String name = "小明"; int age = 12; // 一般輸出 System.out.println("name: " + name + " ,age: " + age); // 列印流輸出 String format = "name: %s ,age: %d"; Object[] data = { "小明", 12 }; System.out.printf(format, data); System.out.println(); // 列印流簡化輸出 System.out.printf("name: %s ,age: %d", data); }}
輸出1:
name: 小明 ,age: 12name: 小明 ,age: 12name: 小明 ,age: 12
小結1:列印流為Java提供了一種類似於C/C++的格式化列印,其實只是一種列印的補充格式。因為在Java語言中,System.out.println()通過+號重載可以實現字符串拼接,可以拼接出任何列印格式,所以說System.out.printf()只是提供了另一種列印格式的輸出方式。
代碼2——掃描流:
package mypackage_掃描類;import java.util.Scanner;//java.util.Scanner類:掃描器類,表示輸入操作.//存在的方法: xxx表示數據類型,如byte,int ,boolean等.// boolean hasNextXxx():判斷是否有下一種類型的數據// Xxx nextXxx():獲取下一個該類型的數據.public class Test { public static void main(String[] args) { Scanner scanner = new Scanner("Java程式設計師就業前景好,薪資高!一起來學習Java吧!"); while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println(line); } scanner.close(); }}
輸出2:
Java程式設計師就業前景好,薪資高!一起來學習Java吧!
小結2:掃描類中,hasNextXxx()和nextXxx()兩個方法,將字符串內容(也可以是其他內容txt、數組、boolean等)列印出來。
列印流定義:
(1)列印到控制臺;
(2)解釋了System.out.println()底層原理,System.out.println();其實等價於 PrintStream ps =
System.out; ps.println(),且見代碼1;
掃描流定義:
與列印流對應,解釋了控制到輸入底層原理,本質上是java.util.Scanner類:掃描器類,表示輸入操作,且見代碼2。
代碼1:列印流為Java提供了一種類似於C/C++的格式化列印,其實只是一種列印的補充格式。因為在Java語言中,System.out.println()通過+號重載可以實現字符串拼接,可以拼接出任何列印格式,所以說System.out.printf()只是提供了另一種列印格式的輸出方式。
代碼2:掃描類中,hasNextXxx()和nextXxx()兩個方法,將字符串內容(也可以是其他內容txt、數組、boolean等)列印出來。
注意:Java BIO流中,列印流用於列印到控制臺,掃描流用於讀入,甚至可將兩個流放在一起寫一個demo,可以嘗試一下。
數據流定義:提供了可以讀/寫任意數據類型的方法,分別是:
DataOutputStream: 提供了 writeXxx(xxx value)方法.
DataInputStream: 提供了 readXxx()方法.
注意: writeXxx和readXxx必須要對應起來, writeByte寫出的數據,此時只能使用readByte讀取回來.且見代碼1.
代碼1——數據流讀寫任意類型數據:
package mypackage;//數據流,提供了可以讀/寫任意數據類型的方法://DataOutputStream: 提供了 writeXxx(xxx value)方法.//DataInputStream: 提供了 readXxx()方法.// 注意: writeXxx和readXxx必須要對應起來, writeByte寫出的數據,此時只能使用readByte讀取回來.import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;public class Test { // 先寫出到data.txt文件中去,然後再讀入程序,再列印出來 public static void main(String[] args) throws Exception { File file = new File("data.txt"); write(file); read(file); } private static void read(File file) throws Exception { DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file)); System.out.println(dataInputStream.readByte()); System.out.println(dataInputStream.readChar()); System.out.println(dataInputStream.readUTF()); dataInputStream.close(); } private static void write(File file) throws Exception { DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(file)); dataOutputStream.writeByte(12); dataOutputStream.writeChar('男'); dataOutputStream.writeUTF("小明"); dataOutputStream.close(); }}
輸出1:
12男小明
小結1:理論上,數據流可以讀寫任意類型的數據,8種基本類型(boolean char float double byte short int long),字符串(readChars、readUTF),數組(int數組、byte數組),程序(代碼1)為縮減程序,只寫了三種(byte char utf字符串)。
數據流定義:提供了可以讀/寫任意數據類型的方法,兩個實現類,每個實現類都有writeXxx()和readXxx()方法。
分別是:
DataOutputStream: 提供了 writeXxx(xxx value)方法.
DataInputStream: 提供了 readXxx()方法.
注意: writeXxx和readXxx必須要對應起來, writeByte寫出的數據,此時只能使用readByte讀取回來.且見代碼1.
數據流的使用:提供了可以讀/寫任意數據類型的方法,任意數據類型是指8種基本類型(boolean char float double byte short int long),字符串(readChars、readUTF),數組(int數組、byte數組),均有相應的readXxx()和WriteXxx()方法。
Java管道流定義:實現兩個線程之間的數據交互。
包括四種:管道字節輸入流PipedInputStream、管道字節輸出流PipedOutputStream、
管道字符輸入流PipedReder、管道字符輸出流PipedWriter。
管道字節輸入流PipedInputStream、管道字節輸出流PipedOutputStream:
package mypackage;import java.io.PipedInputStream;import java.io.PipedOutputStream;//管道流:實現兩個線程之間的數據交互.//PipedInputStream//PipedOutputStream//PipedReder//PipedWriter//ThreadA使用寫出流不斷寫出,ThreadB中注入ThreadA引用,讀取ThreadA寫出流中的內容,不斷列印到控制臺public class Test { public static void main(String[] args) throws Exception { ThreadA threadA = new ThreadA(); ThreadB threadB = new ThreadB(threadA); threadA.start(); threadB.start(); }}class ThreadA extends Thread { private PipedOutputStream pipedOutputStream = new PipedOutputStream(); public PipedOutputStream getOut() { return pipedOutputStream; } @Override public void run() { // run()方法中定義這個線程啟動後具體幹什麼事情 try { for (int i = 65; i < 65 + 26; i++) { pipedOutputStream.write(i); } pipedOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } }}class ThreadB extends Thread { PipedInputStream pipedInputStream = null; public ThreadB(ThreadA threadA) throws Exception { pipedInputStream = new PipedInputStream(threadA.getOut()); } @Override public void run() { try { int len = -1; while ((len = pipedInputStream.read()) != -1) { System.out.print((char) len); } pipedInputStream.close(); } catch (Exception e) { e.printStackTrace(); } }}
輸出1:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1、新建一個ThreadA線程,ThreadA使用管道寫出流不斷寫出,ThreadB中注入ThreadA引用,讀取ThreadA寫出流中的內容,不斷列印到控制臺。
2、不管哪個線程,run()方法中定義這個線程啟動後具體幹什麼事情,ThreadA的run()方法就是不斷寫出,ThreadB的run()就是讀取ThreadA寫出流中的內容,不斷列印到控制臺。
Java管道流定義:實現兩個線程之間的數據交互。
1、新建一個ThreadA線程,ThreadA使用管道寫出流不斷寫出,ThreadB中注入ThreadA引用,讀取ThreadA寫出流中的內容,不斷列印到控制臺。
2、不管哪個線程,run()方法中定義這個線程啟動後具體幹什麼事情,ThreadA的run()方法就是不斷寫出,ThreadB的run()就是讀取ThreadA寫出流中的內容,不斷列印到控制臺。
合併流定義:JavaIO流——合併流,接收兩個輸入流作為參數,合併兩個輸入流或合併流,對外形成一個更大的流,方便客戶端操作。
合併流需要注意的點:
1、合併流對應的對象是輸入流,是對輸入流合併,不是對輸出流合併;
2、因為不同輸入流有不同對應txt文件,用合併流將兩個輸入流合併後,可以輸入兩個文件,注意合併的是兩個輸入流而不是兩個源文件。
3、合併流可以接收合併流作為實際參數,形成多個流的合併,也稱合併嵌套。
1.1 序列化和反序列化定義:
序列化: 指把堆內存中的Java對象數據,通過某種方式把對象存儲到磁碟文件中或者傳遞給其他網絡的節點(在網絡上傳輸). 我們把這個過程稱之為序列化.
反序列化:把磁碟文件中的對象數據或者把網絡節點上的對象數據,恢復成Java對象的過程.
1.2 為什麼要做序列化:
1):在分布式系統中,需要共享的數據的JavaBean對象,都得做序列化,此時需要把對象再網絡上傳輸,此時就得把對象數據轉換為二進位形式.以後存儲在HttpSession中的對象,都應該實現序列化接口(只有實現序列化接口的類,才能做序列化操作).
2):服務鈍化:如果服務發現某些對象好久都沒有活動了,此時伺服器就會把這些內存中的對象,持久化在本地磁碟文件中(Java對象–>二進位文件). 如果某些對象需要活動的時候,現在內存中去尋找,找到就使用,找不到再去磁碟文件中,反序列化我們得對象數據,恢復成Java對象.
1.3 Java對象流——JavaIO流中實現序列化的方式
使用對象流來完成序列化和反序列化操作:
ObjectOutputStream: 通過writeObject方法做序列化操作的.
ObjectInputStream: 通過readObject方法做反序列化操作的.
ObjectOutputStream ObjectInputStream,提供一種序列化方式,序列化方式有很多,現在網際網路大廠常用的是protobuf,最高效的系列化方式
代碼1:因為實體類Person沒有實現序列化接口Serializable,所以這裡程序拋出異常java.io.NotSerializableException。
代碼2:實體類Person實現序列化接口後,成功解決了程序異常,一般來說,隨著項目的升級,系統的class文件也會升級(增加一個欄位/刪除一個欄位), Java通過serialVersionUID(序列化版本號)來判斷字節碼是否發生改變.所以我們為實體類Person添加一個序列化版本號。
代碼3:給實體類Person加上序列化版本號之後,整個問題正是解決。
JavaIO流——對象流通過writeObject()或readObject()實現序列化和反序列化,在磁碟讀寫和網絡請求中保證數據的正確性。
列印流定義:
(1)列印到控制臺;
(2)解釋了System.out.println()底層原理,System.out.println();其實等價於 PrintStream ps = System.out; ps.println(),且見代碼1;
掃描流定義:
與列印流對應,解釋了控制到輸入底層原理,本質上是java.util.Scanner類:掃描器類,表示輸入操作,且見代碼2。
代碼1:列印流為Java提供了一種類似於C/C++的格式化列印,其實只是一種列印的補充格式。因為在Java語言中,System.out.println()通過+號重載可以實現字符串拼接,可以拼接出任何列印格式,所以說System.out.printf()只是提供了另一種列印格式的輸出方式。
代碼2:掃描類中,hasNextXxx()和nextXxx()兩個方法,將字符串內容(也可以是其他內容txt、數組、boolean等)列印出來。
注意:Java BIO流中,列印流用於列印到控制臺,掃描流用於讀入,甚至可將兩個流放在一起寫一個demo,可以嘗試一下。
數據流定義:提供了可以讀/寫任意數據類型的方法,兩個實現類,每個實現類都有writeXxx()和readXxx()方法。
分別是:
DataOutputStream: 提供了 writeXxx(xxx value)方法.
DataInputStream: 提供了 readXxx()方法.
注意: writeXxx和readXxx必須要對應起來, writeByte寫出的數據,此時只能使用readByte讀取回來.且見代碼1.
數據流的使用:提供了可以讀/寫任意數據類型的方法,任意數據類型是指8種基本類型(boolean char float double byte short int long),字符串(readChars、readUTF),數組(int數組、byte數組),均有相應的readXxx()和WriteXxx()方法。
Java管道流定義:實現兩個線程之間的數據交互。
1、新建一個ThreadA線程,ThreadA使用管道寫出流不斷寫出,ThreadB中注入ThreadA引用,讀取ThreadA寫出流中的內容,不斷列印到控制臺。
2、不管哪個線程,run()方法中定義這個線程啟動後具體幹什麼事情,ThreadA的run()方法就是不斷寫出,ThreadB的run()就是讀取ThreadA寫出流中的內容,不斷列印到控制臺。
IO,對象傳輸的基石(二),完成了。
天天打碼,天天進步!!!
如果覺得本文有用,可以關注+轉發,您的鼓勵就是我創作的最大動力。