對象流:
使用對象流之前,很明顯需要一個自定義的對象
可是普通的自定義類建立的對象并不能被對象流序列化
我們要讓這個自定義類實作一個Serializable接口(Serializable是一個标志性接口,接口中無任何内容)
例:(省略了構造方法、get/set方法、toString方法)
public class Person implements Serializable{
private String name;
private int age;
}
ObjectOutputStream(對象輸出流):
對象序列化,将對象以流的形式儲存到檔案夾的過程
public ObjectOutputStream(OutputStream out) 建立指定位元組輸出流的對象輸出流對象
File f = new File("a.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
void writeObject(Object obj) 儲存對象到流關聯的檔案中
File f = new File("b.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("jack",22);
oos.writeObject(p);
oos.close();
這樣就完成了對象的序列化到b.txt:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPR5UMVpWT5FkaNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM3gDMyYTM1ETOxgDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
ObjectOutputStream對象輸出流輸出的對象檔案就是亂碼,隻能用對象流檢視檔案内容
ObjectInputStream(對象輸入流):
對象反序列化,将檔案中對象以流的形式讀取出來的過程
public ObjectInputStream(InputStream in) 建立指定位元組輸入流對象的對象輸入流對象
File f = new File("b.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
public final Object readObject () 讀取一個對象
File f = new File("b.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
System.out.println(obj); //輸出:Person{name='jack', age=22}
fis.close();
當儲存好對象後,若對類的内容作了修改,且沒有重新使用對象輸出流輸出一次關聯檔案
則readObject()方法讀取到的關聯檔案時就會出現InvalidClassException異常
因為每次修改類内容(無論是,包括修飾符、成員變量、成員方法)都會改變類中的一個serialVersionUID值
然後再次讀取該對象檔案時,就會出現序列化不同的異常
若不想因為對類内容作了一些微小修改,而導緻源檔案不能被讀取的問題
可以在類中固定好serialVersionUID值,且設定為私有final靜态的!
public class Person implements Serializable{
private String name;
private int age;
private static final long serialVersionUID = 12345L; //固定serialVersionUID為任意一個值
}
若對象序列化時,部分成員變量中的資訊,不想被writeObject寫進檔案中
1.可以将成員變量設定為static靜态成員變量
這樣改成員變量就儲存在類中,建立對象時不會被對象序列化輸出到檔案中
public class Person implements Serializable{
private String name;
private int age1;
private static final long serialVersionUID = 12345L;
private static double high ;
}
弊端:設定為靜态後,反序列化該對象檔案确實不會顯示此成員變量
可是所有Person類對象的high屬性都是固定的,這樣很不靈活、很不實用
2.使用transient關鍵字
使用該關鍵字修飾的成員變量,能保證成員變量的值不被序列化到檔案中,隻會短暫儲存在記憶體中
public class Person implements Serializable{
private String name;
private int age1;
private static final long serialVersionUID = 12345L;
private transient int high ; //transient修飾了high屬性
}
做個測試:使用ObjectOutputStream輸出帶有transient關鍵字修飾的成員變量
File f = new File("a.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("jack",20,22); //寫入被transient關鍵字修飾的high屬性為22
oos.writeObject(p);
oos.close();
然後再用ObjectInputStream檢視該對象是否包含該成員變量的資訊
File f = new File("a.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
Person p = (Person)obj; //将Object對象強轉為Person對象
System.out.println(p.getHigh()); //輸出:0
fis.close();
列印流:
PrintStream類:
public PrintStream(File file) 使用指定的File對象建立列印流對象
File f = new File("b.txt");
PrintStream ps = new PrintStream(f);
public PrintStream(String fileName) 使用指定的檔案名字元串建立列印流對象
PrintStream ps = new PrintStream("b.txt");
PrintStream類的print()和println()方法中可以輸出基本資料類型
其實常用System.out.println輸出語句就是一個列印流的println方法
隻是建立了PrintStream對象時,指定了File對象,調用print方法時輸出的對象變成了文本檔案
PrintStream consolePs = System.out; //用PrintStream對象接受系統輸出
PrintStream ps = new PrintStream("b.txt");
System.setOut(ps); //設定系統輸出流為ps
System.out.println("你好"); //這個"你好" 會列印在b.txt文本内
System.setOut(consolePs); //設定系統輸出流為consolePs
System.out.println("你好"); //這個"你好" 會列印在控制台