1. 程式人生 > >java之IO流(序列化流與反序列化流)

java之IO流(序列化流與反序列化流)

一.物件序列化流ObjectOutputStream

 

用於向流中寫入物件的操作流 ObjectOutputStream   稱為 序列化流

ObjectOutputStream 將 Java 物件的基本資料型別和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)物件。通過在流中使用檔案可以實現物件的持久儲存。

注意:只能將支援 java.io.Serializable 介面的物件寫入流中

構造方法摘要:

ObjectOutputStream(OutputStream out):建立寫入指定OutputStream的ObjectOutputStream。

方法摘要:

writeObject(Object obj):將指定的物件寫入ObjectOutputStream。

//Person類
public class Person implements Serializable {
    private String name;
    private int age;
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        
this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() {
return "Person [name=" + name + ", age=" + age + "]"; } }
//測試類
public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        /*
         * 將一個物件儲存到持久化(硬碟)的裝置上。
         */
        writeObj();//物件的序列化。
    }
    public static void writeObj() throws IOException {
        //1,明確儲存物件的檔案。
        FileOutputStream fos = new FileOutputStream("tempfile\\obj.object");
        //2,給操作檔案物件加入寫入物件功能。
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //3,呼叫了寫入物件的方法。
        oos.writeObject(new Person("wangcai",20));
        //關閉資源。
        oos.close();
    }
}

 

二.物件反序列化流ObjectInputStream

 

ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本資料和物件進行反序列化。支援 java.io.Serializable介面的物件才能從流讀取

構造方法摘要:

ObjectInputStream(InputStream in):建立從指定InputStream讀取的ObjectInputStream。

方法摘要:

readObject(Object obj):從ObjectInputStream讀取物件

public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        readObj();//物件的反序列化。
    }
    public static void readObj() throws IOException, ClassNotFoundException {
        
        //1,定義流物件關聯儲存了物件檔案。
        FileInputStream fis = new FileInputStream("tempfile\\obj.object");
        
        //2,建立用於讀取物件的功能物件。
        ObjectInputStream ois = new ObjectInputStream(fis);
        
        Person obj = (Person)ois.readObject();
        
        System.out.println(obj.toString());
        
    }
}

 

三.序列化介面

 

當一個物件要能被序列化,這個物件所屬的類必須實現Serializable介面。否則會發生異常NotSerializableException異常。同時當反序列化物件時,如果物件所屬的class檔案在序列化之後進行的修改,那麼進行反序列化也會發生異常InvalidClassException。

原因:

1.該類的序列版本號與從流中讀取的類描述符的版本號不匹配

2.該類包含未知資料型別

3.該類沒有可訪問的無引數構造方法

Serializable標記介面。該介面給需要序列化的類,提供了一個序列版本號。serialVersionUID. 該版本號的目的在於驗證序列化的物件和對應類是否版本匹配。

public class Person implements Serializable {
    //給類顯示宣告一個序列版本號。
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    public Person() {
        super();
        
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

 

四.瞬態關鍵字transient

 

當一個類的物件需要被序列化時,某些屬性不需要被序列化,這時不需要序列化的屬性可以使用關鍵字transient修飾。只要被transient修飾了,序列化時這個屬性就不會序列化了。同時靜態修飾也不會被序列化,因為序列化是把物件資料進行持久化儲存,而靜態的屬於類載入時的資料,不會被序列化。

public class Person implements Serializable {
    /*
     * 給類顯示宣告一個序列版本號。
     */
    private static final long serialVersionUID = 1L;
    private static String name;
    private transient/*瞬態*/ int age;
    
    public Person() {
        super();
        
    }
    
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}