2018-04-19

ObjectOutputStream和ObjectInputStream的基本使用詳解



目錄

1、ObjectOutputStream的使用
--1.1、構(gòu)造函數(shù)
--1.2、常用的方法
----1.2.1、將對(duì)象寫(xiě)入到文件中永久存儲(chǔ)
2、ObjectInputStream的使用
--2.1、構(gòu)造函數(shù)
--2.2、常用的方法
----2.2.1、將已經(jīng)序列化的對(duì)象反序列化
3、小結(jié)



在我們講解對(duì)象輸出流和對(duì)象輸入流之前,我們首先要明確兩個(gè)概念:

序列化和反序列化:

  • 將一個(gè)特定的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為一組字節(jié)的過(guò)程稱(chēng)之為序列化

  • 將一組字節(jié)轉(zhuǎn)換為特定的數(shù)據(jù)結(jié)構(gòu)的過(guò)程稱(chēng)之為反序列化

  • 持久化:

  • 將數(shù)據(jù)寫(xiě)入硬盤(pán)長(zhǎng)久保存的過(guò)程稱(chēng)之為持久化

1、ObjectOutputStream的使用

ObjectOutputStream是一個(gè)高級(jí)流, 將 Java 對(duì)象的基本數(shù)據(jù)類(lèi)型和圖形寫(xiě)入 OutputStream??梢允褂?ObjectInputStream 讀?。ㄖ貥?gòu))對(duì)象。通過(guò)在流中使用文件可以實(shí)現(xiàn)對(duì)象的持久存儲(chǔ)。如果流是網(wǎng)絡(luò)套接字流,則可以在另一臺(tái)主機(jī)上或另一個(gè)進(jìn)程中重構(gòu)對(duì)象。

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


1.1、構(gòu)造函數(shù)

//為完全重新實(shí)現(xiàn) ObjectOutputStream 的子類(lèi)提供一種方法,讓它不必分配僅由 ObjectOutputStream 的實(shí)現(xiàn)使用的私有數(shù)據(jù)。
protected ObjectOutputStream();

//創(chuàng)建寫(xiě)入指定 OutputStream 的 ObjectOutputStream。此構(gòu)造方法將序列化流部分寫(xiě)入底層流;調(diào)用者可以通過(guò)立即刷新流,確保在讀取頭部時(shí),用于接收 ObjectInputStreams 構(gòu)造方法不會(huì)阻塞。
public ObjectOutputStream(OutputStream out);

1.2、常用的方法

我們這里重點(diǎn)講述的是將一個(gè)對(duì)象實(shí)例化之后存儲(chǔ)到文件中,其他的write()方法請(qǐng)參看API。

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

1.2.1、將對(duì)象寫(xiě)入到文件中永久存儲(chǔ)

Person類(lèi)

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

//Person類(lèi)實(shí)現(xiàn)了Serializable接口,所以該類(lèi)才能被序列化;反之,如果沒(méi)有實(shí)現(xiàn)該接口的類(lèi)則不能被序列化。
public class Person implements Serializable{
    /**
     * 序列化的ID,只要加了該版本號(hào),在反序列化的時(shí)候不論你的類(lèi)的屬性是否改變,只要是版本號(hào)不變那么盡經(jīng)可能的兼容新版本。
     * 如果版本號(hào)改變了,那么反序列化的過(guò)程中就會(huì)拋出異常。
     */
    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對(duì)象寫(xiě)入到文件中

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

import tools.Person;

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

2、ObjectInputStream的使用

ObjectInputStream也是一個(gè)高級(jí)流,對(duì)以前使用 ObjectOutputStream 寫(xiě)入的基本數(shù)據(jù)和對(duì)象進(jìn)行反序列化。


2.1、構(gòu)造函數(shù)

//為完全重新實(shí)現(xiàn) ObjectInputStream 的子類(lèi)提供一種方式,讓它不必分配僅由 ObjectInputStream 的實(shí)現(xiàn)使用的私有數(shù)據(jù)。
protected ObjectInputStream();

//創(chuàng)建從指定 InputStream 讀取的 ObjectInputStream。從流讀取序列化頭部并予以驗(yàn)證。在對(duì)應(yīng)的 ObjectOutputStream 寫(xiě)入并刷新頭部之前,此構(gòu)造方法將阻塞。
public ObjectInputStream(InputStream in);

2.2、常用的方法

我們這里;里主要講述的是將已經(jīng)序列化之后存儲(chǔ)在文件中的對(duì)象反序列化的過(guò)程,其他的read()方法請(qǐng)參看API。

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

注意看,以上的方法返回的是一個(gè)Object,所以我們?cè)诜葱蛄谢倪^(guò)程中需要強(qiáng)制轉(zhuǎn)換為我們所需要的類(lèi)型。

2.2.1、將已經(jīng)序列化的對(duì)象反序列化

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

import tools.Person;

/**
 * ObjectInputStream:高級(jí)流,對(duì)象輸入流
 * ObjectInputStream 對(duì)以前使用 ObjectOutputStream 寫(xiě)入的基本數(shù)據(jù)和對(duì)象進(jìn)行反序列化。
 * 有支持 java.io.Serializable 或 java.io.Externalizable 接口的對(duì)象才能從流讀取。
 * @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);
    }
}

運(yùn)行結(jié)果:
運(yùn)行結(jié)果.PNG

3、小結(jié)

ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時(shí),可以為應(yīng)用程序提供對(duì)對(duì)象圖形的持久存儲(chǔ)。ObjectOutputStream用于序列化對(duì)象,ObjectInputStream 用于恢復(fù)那些以前序列化的對(duì)象(反序列化)。其他用途包括使用套接字流在主機(jī)之間傳遞對(duì)象,或者用于編組和解組遠(yuǎn)程通信系統(tǒng)中的實(shí)參和形參。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容