java.io.DataInput接口和java.io.DataOutput接口詳解

DataInput和DataOutput兩個接口分別提供了從流中讀取二進制數據轉化爲java基本數據和向流中寫入由java基本數據轉成的二進制數據,功能十分強大。

一、DataInput 接口用於從二進制流中讀取字節,並重構所有 Java 基本類型數據。同時還提供根據 UTF-8 修改版格式的數據重構 String 的工具。

對於此接口中的所有數據讀取例程來說,如果在讀取到所需字節數的數據之前已經到達文件末尾 (end of file),則都將拋出 EOFExceptionIOException 的一種)。如果因爲文件末尾以外的其他原因無法讀取字節,則拋出 IOException 而不是 EOFException。尤其在輸入流已關閉的情況下,將拋出 IOException

DataInput類介紹:

package java.io;


public interface DataInput {


    /**
     * 該方法包含一個byte型數組b作爲參數,它將作爲一個數據的緩存區,該方法會從流中讀取一些字節數據並將它們存儲到數據緩存區中,讀取的字節數量取決於數據緩
     * 存區容量的大小。
     * 這個方法是阻塞的,當遇到一下幾種情況會繼續執行:
     * 1.數據緩存區b擁有足夠的容量去容納流中的數據,此時可以正常地返回數據。
     * 2.當文件的結尾已經被檢測到時,這時會拋出一個EOFException。
     * 3.當發生一個I/O異常時,一個不同於EOFException的I/O異常會被拋出。
     * 如果數據緩存區b是爲null的,那麼會拋出一個NullPointerException。
     * 如果數據緩存區b的容量爲0,那麼該方將不能讀取到任何數據,如果不爲0則讀取的數據會依次放入緩存區b中。
     * 當這個方法拋出一個異常時,數據緩存區b中的某些數據會被更新,但不是所有的數據都被更新。
     */
    void readFully(byte b[]) throws IOException;

    /**
     * 該方法包含三個參數,第一個參數是一個byte型數組,用於作爲一個數據的緩存區,第二個參數爲從數據開始存儲的起點,第三個爲讀取數據的長度。
     * 這個方法同樣是阻塞的,直到遇到以下幾種情況:
     * 1.數據緩存區b擁有足夠的容量去存放讀取的數據,這時會正常地返回數據。
     * 2.當一個文件的結尾已經被檢測到時,這時會拋出一個EOFException。
     * 3.當發生一個I/O異常時,一個不同於EOFException的I/O異常會被拋出。
     * 如果數據緩存區b是爲null的,那麼此時會拋出一個NullPointerException。
     * 如果參數off,len爲負數,或者(off+len)大於了數據緩存區b的長度,那麼此時會拋出IndexOutOfBoundsException。
     * 如果參數len爲0,那麼該方法將不會讀取任何的數據,否則正常情況下,讀取的數據會依次存放於數據緩存區b中,起點從off開始,依次往後。
     * 參數len決定了一次讀取的最多字節數。
     */
    void readFully(byte b[], int off, int len) throws IOException;

    /**
     * 該方法試圖從數據流中跳過n個字節的數據,並且拋棄被跳過的字節數據,但是它可能跳過一些比較少的字節,甚至是0個字節。這樣會導致一些意外的狀況。在n個字
     * 字節被跳過之前便到達文件結束處,這隻有一種可能性。這個方法從未拋出過EOFException。該方法最終返回一個int型數據,該數據爲本方法實際跳過的字節數據的
     * 數量。 
     */
    int skipBytes(int n) throws IOException;

    /**
     * 該方法從流中讀取一個字節的數據,並返回相應的boolean類型的值。如果讀取的數據爲0則爲false,否則爲true。這個方法適用於讀取DataOutput接口中writeBoolean
     * 方法寫入的數據。
     */
    boolean readBoolean() throws IOException;

    /**
     * 該方法用於讀取並返回一個字節數據。被讀取的字節會被當做一個範圍爲-127~128的有符號數。這個方法適合讀取由DataOutput接口中writeByte方法寫入的數據。
     */
    byte readByte() throws IOException;

    /**
     * 該方法讀取一個字節的數據,並採用零擴展的方式,將其擴展爲一個int型數據,並返回這個值,它的範圍是0~255。這個方法適合讀取由DataOutput接口中由writeByte
     * 方法寫入的數據,當然寫入的數據範圍也必須在0~255之間。
     */
    int readUnsignedByte() throws IOException;

    /**
     * 該方法讀取兩個字節數據,並返回一個short類型的數據。假設讀取的第一個字節數據爲a,第二個字節數據爲b,那麼最後通過下面的小操作將其轉換成short類型的數
     * 據並返回:(short)((a << 8) | (b & 0xff)),通過這個操作得到一個16位的數據,低八位爲b,高八位爲a。
     * 這個方法適合讀取由DataOutput接口中由writeShort方法來寫入的數據。
     */
    short readShort() throws IOException;

    /**
     * 該方法讀取兩個字節數據,並返回一個int型數據,取值範圍爲0~65535。假設讀取的第一個字節數據爲a,第二個字節數據爲b,那麼最後通過下面的小操作將其轉換成
     * int型數據:((a & 0xff) << 8 | b & 0xff),因爲求的是無符號數,所以都要進行&0xff的操作。低八位爲b,高八位爲a。
     * 這個方法適合讀取由DataOutput接口中由writeShort方法來寫入的數據。
     */
    int readUnsignedShort() throws IOException;

    /**
     * 該方法讀取兩個字節數據,並返回一個char類型的數據。假設讀取的第一個字節數據爲啊,第二個字節數據爲b,那麼最後通過下面的小操作將其轉換成char型的數據,
     * 並返回:(char)((a << 8) | b & 0xff),這個方法適合讀取由DataOutout接口中由writeChar方法寫入的數據。	
     */
    char readChar() throws IOException;

    /**
     * 該方法讀取四個字節數據,並返回一個int類型的數據。假設讀取的第一個字節數據爲a,第二個爲b,以此類推,那麼最後通過下面的小操作將其轉換成int型的數據:
     * (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)),這個方法適合讀取由DataOutput接口中由writeInt方法寫入的數據。
     */
    int readInt() throws IOException;

    /**
     * 該方法讀取八個字節數據,並返回一個long類型的數據。假設讀取的第一個字節數據爲a,第二個爲b,以此類推,那麼最後通過下面的小操作將其轉換成long型的數據:
     * (((long)(a & 0xff) << 56) | ((long)(b & 0xff) << 48) | ((long)(c & 0xff) << 40) | ((long)(d & 0xff) << 32) | ((long)(e & 0xff) << 24) 
     * | ((long)(f & 0xff) << 16) | ((long)(g & 0xff) <<  8) | ((long)(h & 0xff))),這個方法適合讀取由DataOutput接口中由writeLong方法寫入的數據。
     */
    long readLong() throws IOException;

    /**
     * 該方法讀取四個字節數據,開始時,採用readInt的方法來獲取一個int型數據,然後通過Float.intBitsToFloat方法來獲得一個float型數據,該方法適合讀取由
     * DataOutput接口中由writeFloat方法寫入的數據。
     */
    float readFloat() throws IOException;

    /**
     * 該方法讀取八個字節數據,開始時,採用readLong的方法來獲取一個long型數據,然後通過Double.longBitsToFloat方法來獲得一個double型數據,該方法適合讀取
     * 由DataOutput接口中由writeDouble方法寫入的數據。
     */
    double readDouble() throws IOException;

    /**
     * 該方法從流中讀取下一行數據。方法從流中連續讀取字節數據,並將每一個字節的數據都轉換成一個字符,直到遇到換行符或者文件讀取結束爲止。這些被讀取並轉
     * 的字符最終將組成一個String類型的字符串並返回。要注意的是因爲這個方法處理的是字節數據,所以它不支持完全由Unicode編碼來進行輸入的數據的讀取。
     * 如果文件結束卻並沒有讀取到任何數據,那麼該方法將返回一個null,若果讀取到,則每一個字節都通過零擴展的方式轉換成char型數據。
     * 如果遇到'\n',那麼該字符會被丟棄,同時讀取操作終止。如果遇到'\r'且之後緊跟着'\n',那麼這兩個字符都被丟棄,並且終止讀取操作,當然如果文件已經讀取到了
     * 結尾,那麼同樣會終止讀取操作。讀取操作終止後,那麼所有讀取的沒被丟棄的字符,便會組成一個字符串並返回。值得注意的是,字符串中的每一個字符的值,都會
     * 小於‘\u005Cu0100’,它就是(char)256。
     */
    String readLine() throws IOException;

    /**
     *該方法用於讀取一個由utf-8格式編碼的數據,因爲其內部過程不是很懂,這裏就不多說了T_T
     */
    String readUTF() throws IOException;
}

 

DataOutput類介紹:

package java.io;

public interface DataOutput {
    /**
     * 取傳入int型數據的低八位數據寫入輸出流中。
     */
    void write(int b) throws IOException;

    /**
     * 將傳入的字節數組中的所有數據都寫入輸出流之中,如果傳入的字節數組爲null,那麼會拋出一個NullPointerException,如果傳入的字節數組的容量爲0,那麼不會寫
     *任何的數據,如果不爲0,則會依次取出字節數組中的數據,寫入到輸出流中。
     */
    void write(byte b[]) throws IOException;

    /**
     * 將傳入的字節數組從off位置開始往後length長度的數據寫入到輸出流中,如果傳入的字節數組b爲null,那麼會拋出一個NullPointerException。如果off或者len爲負
     * 數亦或是(off+len)的總長度大於了字節數組的總容量,那麼此時會拋出一個IndexOutOfBoundsException。如果len爲0,那麼不會向流中寫入任何數據。如果不爲0,
     * 則會把字節數組中的數據依次寫入到輸出流中。
     */
    void write(byte b[], int off, int len) throws IOException;

    /**
     * 該方法向輸出流中寫入一個boolean類型的值,如果傳入的boolean型參數v是true,那麼向流中寫入1,如果傳入的boolean型參數v是false,那麼向流中寫入0。
     * 通過這個方法向流中寫入的boolean型數據,需要通過DataInput接口中的readBoolean方法讀取,它會再從流中讀取0/1,轉換成相應的boolean型數據。
     */
    void writeBoolean(boolean v) throws IOException;

    /**
     * 該方法將截取傳入參數的低八位寫入輸出流中,高24位將被忽略。從這可以看出該操作與前面的write方法是一模一樣的。通過這個方法向流中寫入的Byte型數據,需
     * 要通過DataInput接口中的readByte方法讀取。
     */
    void writeByte(int v) throws IOException;

    /**
     * 向輸出流中寫入兩個字節的數據,通過(byte)(0xff & (v >> 8))和(byte)(0xff & v)兩個小操作來分別得到需要寫入的數據,即int型數據後16位中的高8位和低八位
     * 通過該方法向輸出流中寫入的Short型數據,需要通過DataInput接口中的readShort方法來獲取。
     */
    void writeShort(int v) throws IOException;

    /**
     * 該方法向輸出流中寫入一個包含兩個字節的char型數據,通過(byte)(0xff & (v >> 8))和(byte)(0xff & v)兩個小操作來得到需要寫入的數據。通過該方法向輸出流
     * 中寫入的char型數據,需要通過DataInput接口中的readChar方法來獲取。
     */
    void writeChar(int v) throws IOException;

    /**
     * 該方法向輸出流中寫入一個包含四個字節的int型數據,通過(byte)(0xff & (v >> 24))、(byte)(Oxff & (v >> 16))、(byte)(Oxff & (v >> 8))和(byte)(Oxff & v)
     * 四個小操作來得到需要寫入的數據。通過該方法向輸出流中寫入的int型數據,需要通過DataInput接口中的readInt方法來進行讀取。
     */
    void writeInt(int v) throws IOException;

    /**
     * 該方法向輸出流中寫入一個包含八個字節的long型數據,通過(byte)(0xff & (v >> 56))、(byte)(0xff & (v >> 48))、(byte)(0xff & (v >> 40))、
     * (byte)(0xff & (v >> 32))、(byte)(0xff & (v >> 24))、(byte)(0xff & (v >> 16))、(byte)(0xff & (v >>  8))和(byte)(0xff & v)八個小操作來得到需要寫入
     * 數據。通過該方法向輸出流中寫入的int型數據,需要通過DataInput接口中的readLong方法來進行讀取。
     */
    void writeLong(long v) throws IOException;

    /**
     * 該方法向流中寫入一個包含4個字節的float型數據,它其實是先將數據轉變爲int型數據,使用Float.floatToIntBits方法進行轉換,然後通過writeInt方法向輸出流
     * 寫入數據。通過該方向輸出流中寫入的Float型數據,需要通過DataInput接口中的readFloat方法來進行讀取。
     */
    void writeFloat(float v) throws IOException;

    /**
     * 該方法向流中寫入一個包含8個字節的double型數據,它其實是先將數據轉變爲long型數據,使用Double.doubleToLongBits方法進行轉換,然後通過writeLong方法向輸
     * 出流 寫入數據。通過該方向輸出流中寫入的Double型數據,需要通過DataInput接口中的readDouble方法來進行讀取。
     */
    void writeDouble(double v) throws IOException;

    /**
     * 該方法用於將傳入String類型s中的每個字符寫入輸出流中。寫入時將String型數據拆分成一個個字符,每個字符佔用一個字節。如果傳入的字符串數據s是一個null,
     * 那麼此時會拋出 一個NullPointerException。如果傳入的字符串參數s的長度爲0,那麼該方法不會向輸出流寫入任何數據。否則,會將字符串s依次寫入到輸出流中。
     * 單個字符寫入的時候採用writeByte方法,高位的值沒有實際意義,被忽略。
     */
    void writeBytes(String s) throws IOException;

    /**
     * 該方法用於將傳入String類型s中的每個字符寫入輸出流中。寫入時將String型數據拆分成一個個字符,每個字符佔用兩個字節。如果傳入的字符串數據s是一個null,
     * 那麼此時會拋出 一個NullPointerException。如果傳入的字符串參數s的長度爲0,那麼該方法不會向輸出流寫入任何數據。否則,會將字符串s依次寫入到輸出流中。
     * 單個字符寫入的時候採用writeChar方法。
     */
    void writeChars(String s) throws IOException;

    /**
     * 該方法將傳入的字符串s以utf-8的編碼格式寫入輸出流中,通過該方法向輸出流中寫入的數據可以通過DataInput接口中的readUTF來進行讀取。因爲具體牽扯到編碼,
     * 筆者比較菜,這裏就不多說了T_T
     */
    void writeUTF(String s) throws IOException;
}

 

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