I/O流中的BufferedXXXStream與DataXXXStream、ObjectXXStream

徐睿-上海發表於2020-10-06

1、通過兩張圖快速看一下IO流中的一些基礎知識

通過上述的圖,我們知道實際開發中都是用Bufered流來對基本的流進行包裝,加快讀寫速度(一次8K緩衝),減少頻繁對IO進行存取操作,提升效率。但在實際開發中,我們需要提前定義一個byte陣列來接收或讀取一次的讀入資料,然後再一塊一塊的讀取或寫入檔案中,針對某些二進位制型別如BLOB的資料或檔案比較佔優勢,但針對一些需要寫入或讀取時帶型別的資料時就需要頻繁進行資料轉換,既麻煩又不太適合,當然,我們也可以考慮直接用序列化來進行物件持久化儲存,但序列化的檔案通常都比較大,不利於網路的傳輸。

2、比序列化更輕量化的資料寫入與讀取方式

在一個分散式的檔案系統中,當涉及大量資料進行操作時,這種方式就特別佔優勢,按以下檔案寫入大小,佔用檔案為31個位元組,特別適合於大量檔案頻繁進行交換時,所以在mapreduce中大量採用了writable的模式進行了二次封裝,同dataXXXstream使用了同樣的方式,而不再使用序列化的方式。

//順序讀入
    private static void read() throws IOException {
        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("mytext.txt")));
        System.out.println(dis.readInt());
        System.out.println(dis.readBoolean());
        System.out.println(dis.readChar());
        System.out.println(dis.readDouble());
        System.out.println(dis.readFloat());
        System.out.println(dis.readUTF());
    }

    //順序寫入不同的資料
    private static void write() throws IOException {
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("mytext.txt")));
        dos.writeInt(22);
        dos.writeBoolean(false);
        dos.writeChar('A');
        dos.writeDouble(454.6d);
        dos.writeFloat(324f);
        //與入string
        dos.writeUTF("helloworld");
        dos.close();
    }

同樣,當我們不使用序列化的writeobject來序列化時,它實現的和dataXXXstream是一樣的功能:

private static void writeobject() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream((new BufferedOutputStream(new FileOutputStream("mytext2.txt"))));
        oos.writeInt(22);
        oos.writeBoolean(false);
        oos.writeChar('A');
        oos.writeDouble(454.6d);
        oos.writeFloat(324f);
        oos.writeUTF("helloworld");
        oos.close();
    }

出來的檔案大小為36位元組,差別基本可以忽略不計。如果使用了序列化後

        c.setV1(22);
        c.setV2(false);
        c.setV3('A');
        c.setV4(454.6d);
        c.setV5(324f);
        c.setV6("helloworld");
        ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("mytext5.txt")));
        oos.writeObject(c);
        oos.close();

檔案大小:118位元組,大約是三倍大小

所以序列化只針對於對網路與傳輸要求不高的場合提供通用的資料交換,但對於一些嚴格的地方,很少用它來做傳輸

相關文章