Java中ObjectOutputStream和ObjectInputStream的基本使用詳解

在我們講解對象輸出流和對象輸入流之前,我們首先要明確兩個概念:
- 序列化和反序列化:
- 將一個特定的數據結構轉換爲一組字節的過程稱之爲序列化
- 將一組字節轉換爲特定的數據結構的過程稱之爲反序列化
- 持久化:
- 將數據寫入硬盤長久保存的過程稱之爲持久化


ObjectOutputStream的使用

ObjectOutputStream是一個高級流, 將 Java 對象的基本數據類型和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)對象。通過在流中使用文件可以實現對象的持久存儲。如果流是網絡套接字流,則可以在另一臺主機上或另一個進程中重構對象。

注意:只能將支持 java.io.Serializable 接口的對象寫入流中。每個 serializable 對象的類都被編碼,編碼內容包括類名和類簽名、對象的字段值和數組值,以及從初始對象中引用的其他所有對象的閉包。


構造函數

//爲完全重新實現 ObjectOutputStream 的子類提供一種方法,讓它不必分配僅由 ObjectOutputStream 的實現使用的私有數據。
protected ObjectOutputStream();

//創建寫入指定 OutputStream 的 ObjectOutputStream。此構造方法將序列化流部分寫入底層流;調用者可以通過立即刷新流,確保在讀取頭部時,用於接收 ObjectInputStreams 構造方法不會阻塞。
public ObjectOutputStream(OutputStream out);

常用的方法

我們這裏重點講述的是將一個對象實例化之後存儲到文件中,其他的write()方法請參看API。

//將指定的對象寫入 ObjectOutputStream。對象的類、類的簽名,以及類及其所有超類型的非瞬態和非靜態字段的值都將被寫入。
public final void writeObject(Object obj);

將對象寫入到文件中永久存儲

Person類

import java.io.Serializable;
import java.util.ArrayList;

//Person類實現了Serializable接口,所以該類才能被序列化;反之,如果沒有實現該接口的類則不能被序列化。
public class Person implements Serializable{
    /**
     * 序列化的ID,只要加了該版本號,在反序列化的時候不論你的類的屬性是否改變,只要是版本號不變那麼盡經可能的兼容新版本。
     * 如果版本號改變了,那麼反序列化的過程中就會拋出異常。
     */
    private static final long serialVersionUID = 6871740251451383067L;
    private String name;
    private int age;
    private char sex;
    private ArrayList<String> other;

    public Person(){

    }
    public Person(String name, int age, char sex, ArrayList<String> other) {
        super();
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.other = other;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age)throws Exception {
        this.age = age;
    }
    public char getSex() {
        return sex;
    }
    public void setSex(char sex) {
        this.sex = sex;
    }
    public ArrayList<String> getOther() {
        return other;
    }
    public void setOther(ArrayList<String> other) {
        this.other = other;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }


}

將Person對象寫入到文件中

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import tools.Person;

/**
 * ObjectOutputStream:高級流,對象輸出流,只能將支持 java.io.Serializable 接口的對象寫入流中
 *
 * 將一個特定的數據結構轉換爲一組字節的過程稱之爲序列化
 * 將一組字節轉換爲特定的數據結構的過程稱之爲反序列化
 * 將數據寫入硬盤長久保存的過程稱之爲持久化
 *
 * @author Administrator
 *
 */
public class OOSDemo01 {
    public static void main(String[] args){
        try {
            ArrayList<String> other=new ArrayList<String>();
            other.add("清華大學");
            other.add("軟件學院");
            other.add("軟件工程");
            Person person=new Person("小明", 22, '男', other);
            FileOutputStream fos=new FileOutputStream("OOS.txt");
            ObjectOutputStream oos=new ObjectOutputStream(fos);
            //將一個對象經行序列化時需要實現Serializable接口
            oos.writeObject(person);
            oos.flush();
            oos.close();
            System.out.println("對象寫入成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ObjectInputStream的使用

ObjectInputStream也是一個高級流,對以前使用 ObjectOutputStream 寫入的基本數據和對象進行反序列化。


構造函數

//爲完全重新實現 ObjectInputStream 的子類提供一種方式,讓它不必分配僅由 ObjectInputStream 的實現使用的私有數據。
protected ObjectInputStream();

//創建從指定 InputStream 讀取的 ObjectInputStream。從流讀取序列化頭部並予以驗證。在對應的 ObjectOutputStream 寫入並刷新頭部之前,此構造方法將阻塞。
public ObjectInputStream(InputStream in);

常用的方法

我們這裏;裏主要講述的是將已經序列化之後存儲在文件中的對象反序列化的過程,其他的read()方法請參看API。

//從 ObjectInputStream 讀取對象。對象的類、類的簽名和類及所有其超類型的非瞬態和非靜態字段的值都將被讀取。
public final Object readObject();

注意看,以上的方法返回的是一個Object,所以我們在反序列化的過程中需要強制轉換爲我們所需要的類型。

將已經序列化的對象反序列化

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

import tools.Person;

/**
 * ObjectInputStream:高級流,對象輸入流
 * ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本數據和對象進行反序列化。
 * 有支持 java.io.Serializable 或 java.io.Externalizable 接口的對象才能從流讀取。
 * @author Administrator
 *
 */
public class OISDemo01 {
    public static void main(String[] args){
        try {
            FileInputStream fis=new FileInputStream("OOS.txt");
            ObjectInputStream ois=new ObjectInputStream(fis);
            Person person=(Person)ois.readObject();
            System.out.println(person.getName());
            System.out.println(person.getAge());
            System.out.println(person.getSex());
            ArrayList<String> other=person.getOther();
            for (String string : other) {
                System.out.println(string);
            }
            ois.close();
            System.out.println("反序列化成功!");
        } catch (Exception e) {
                e.printStackTrace();
        }
        System.exit(0);
    }
}

運行結果:

運行結果


小結

ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時,可以爲應用程序提供對對象圖形的持久存儲。ObjectOutputStream用於序列化對象,ObjectInputStream 用於恢復那些以前序列化的對象(反序列化)。其他用途包括使用套接字流在主機之間傳遞對象,或者用於編組和解組遠程通信系統中的實參和形參。


以上內容只代表我個人的觀點,有什麼錯誤的地方請各路大神指正!轉載請註明出處!謝謝!

每天進步一點點!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章