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;
}

 

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