天天看點

(四)IO流——對象流、列印流

對象流:

使用對象流之前,很明顯需要一個自定義的對象

可是普通的自定義類建立的對象并不能被對象流序列化

我們要讓這個自定義類實作一個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:

(四)IO流——對象流、列印流

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()方法中可以輸出基本資料類型

(四)IO流——對象流、列印流

其實常用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("你好");                    //這個"你好" 會列印在控制台