A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

DataInputStream为数据输入流,它允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型。
DataOutputStream为数据输出流,它允许应用程序以适当方式将基本 Java数据类型写入输出流中。

阅读源码需要复习一些基础知识,比如基本数据类型、位移运算、&xFF操作。

先来复习下基本数据类型各有多少位。

基本数据类型
byte
short
int
long
float
double
boolean
char

8
16
32
64
32
64
1
16


再来复习下位移运算符中的<<和>>>。

<<表示左移运算符,是将运算符左边的对象,向左移动运算符右边指定的位数,并且在低位补零。其实,向左移n 位,就相当于乘上2 的n 次方。

如,20 < 2;20的二进制为 0001 0100,右移2位后为 0010 1000,则结果就为 40;

>>>表示无符号右移,也叫逻辑右移。即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。

如,20 >>> 2;20的二进制为 0001 0100,右移2位后为 0000 0101,则结果就为 5;
而-20 >> 2;-20的二进制为 1110 1011,右移2位,此时高位补0,即 0011 1010,结果为58;

最后复习下&xFF操作代表什么含义。

取低8位。0xFF是二进制的 1111 1111,那么0000 1010 0101 0101&1111 1111就能取到0000 1010 0101 0101的低8位。

DataInputStream

下面来看下DataInputStream的源码。

/** * DataInput接口用于从二进制流中读取字节,并根据所有Java基本类型数据进行重构。 * 同时还提供根据UTF-8修改版格式的数据重构String的工具。 */public class DataInputStream extends FilterInputStream implements DataInput {    /**     * 构造方法之一     * 使用特定的输出流创建DataInputStream     */    public DataInputStream(InputStream in) {        super(in);    }    /**     * readUTF()使用的数组     */    private byte bytearr[] = new byte[80];    private char chararr[] = new char[80];    /**     * 从输入流中读取b.length个数据保存到byte数组b中。     * 实际读取的字节数以整数的形式返回。     * 在输入数据可用、检测到文件末尾、或抛出异常之前,该方法一直阻塞。     * 如果b为null,会抛出NullPointerException。     * 如果b长度为0,不会读取数据,方法返回值为0;否则会尝试读取至少一个字节。     * 如果因为流在文件末尾导致没有字节可用,将返回-1;否则至少会读取一个字节并保存到b中。     *     * 第一个字节保存到b[0],下一个字节保存到b[1],以此类推。     * 读取的字节数最大等于b的长度。     *     * 此方法等价于read(b, 0, b.length)     *     * @param      b   存储读取数据的byte数组     * @return     实际读取的字节数, 如果因为到达流末尾导致没有数据,返回-1。     * @exception  IOException 如果不是因为流位于文件末尾而无法读取第一个字节;该流已关闭并且底层输入流在关闭后不支持读取操作;发生其他 I/O错误。     */    public final int read(byte b[]) throws IOException {        return in.read(b, 0, b.length);    }    /**     * 从包含的输入流中将最多len个字节读入一个byte数组中。     * 尽量读取len个字节,但读取的字节数可能少于len个,也可能为零。     * 以整数形式返回实际读取的字节数。     * 在输入数据可用、检测到文件末尾或抛出异常之前,此方法将阻塞。     *      * 如果len为零,则不读取任何字节并返回0;     * 否则,尝试读取至少一个字节。如果因为流位于文件未尾而没有字节可用,则返回值-1;     * 否则,至少读取一个字节并将其存储到b中。     *     * @param      b     存储读取数据的缓冲区。     * @param off  目标数组 b 中的起始偏移量     * @param      len   读取的最大字节数。     * @return     读入缓冲区的字节总数;如果因为已经到达流末尾而没有更多的数据,则返回-1。     * @exception  NullPointerException 如果b为null。     * @exception  IndexOutOfBoundsException  如果off为负, len为负,或者len大于b.length-off     * @exception  IOException 如果不是因为流位于文件末尾而无法读取第一个字节;该流已关闭并且底层输入流在关闭后不支持读取操作;发生其他I/O      */    public final int read(byte b[], int off, int len) throws IOException {        return in.read(b, off, len);    }    /**     * 参考DataInput.readFully()的介绍。     *      * 以下是DataInput.readFully()的介绍。     * 从输入流中读取一些字节,并将它们存储在缓冲区数组b中。读取的字节数等于b的长度。     *      * 该方法的执行结果有三种:     * 1.输入数据的 len 个字节是可用的,在这种情况下,正常返回。     * 2.检测到文件末尾,在这种情况下,抛出 EOFException。     * 3.如果发生 I/O 错误,在这种情况下,将抛出 IOException,而不是 EOFException。     *      * 如果b为null,则抛出NullPointerException。     * 如果off为负,或len为负,或者off+len大于数组b的长度,则抛出IndexOutOfBoundsException。     * 如果len为零,则不读取字节。     * 否则,将读取的第一个字节存储到元素b[off]中,下一个字节存储到 b[off+1]中,     * 依此类推。读取的字节数至多等于b[0]。     *      * @param      b  存储读取数据的缓冲区。     * @exception  EOFException  如果此输入流在读取所有字节之前到达末尾。     * @exception  IOException   该流已关闭并且包含的输入流在关闭后不支持读取操作,或者发生其他 I/O 错误。     */    public final void readFully(byte b[]) throws IOException {        readFully(b, 0, b.length);    }    /**     * 参考readFully(byte b[])     *     * @param      b     存储读取数据的缓冲区。     * @param      off   指定数据中的偏移量     * @param      len   指定读取的字节数     * @exception  EOFException  如果此流在读取所有字节之前到达末尾。     * @exception  IOException 该流已关闭并且包含的输入流在关闭后不支持读取操作,或者发生其他I/O错误。     */    public final void readFully(byte b[], int off, int len) throws IOException {        //如果参数不合法,抛出异常        if (len < 0)            throw new IndexOutOfBoundsException();        int n = 0;        //读取字节,直到读取了len个字节        while (n < len) {            int count = in.read(b, off + n, len - n);            //如果此流在读取所有字节之前到达末尾,抛出异常            if (count < 0)                throw new EOFException();            n += count;        }    }    /**     * 参考DataInput.skipBytes()的介绍。     *      * 以下是DataInput.skipBytes()的介绍:     * 试图在输入流中跳过数据的n个字节,并丢弃跳过的字节。     * 不过,可以跳过更少的字节数,该字节数甚至可以为零。     * 这可能由很多情况引起;在已经跳过n个字节前到达文件末尾只是其中的一种可能。此方法从不抛出EOFException。返回实际跳过的字节数。     *     * @param      n  要跳过的字节数     * @return     实际跳过的字节数。     * @exception  IOException 如果包含的输入流不支持查找操作;该流已关闭并且包含的输入流在关闭后不支持读取操作;发生其他I/O错误。     */    public final int skipBytes(int n) throws IOException {        //实际跳过的字节数        int total = 0;        //每次跳过的字节数        int cur = 0;        //如果还没有跳过n个字节,且还没有到达文件末尾,就继续向下跳        while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {            //累加每次跳过的字节数            total += cur;        }        //返回实际跳过的字节数        return total;    }    /**     * 参考DataInput.readBoolean()     *      * 以下是DataInput.readBoolean()的介绍:     *      * 从输入流中读取一个输入字节,如果该字节不是零,则返回true;     * 如果是零,则返回false。此方法适用于读取用接口DataOutput的 writeBoolean方法写入的字节。     *     * @return     如果读取的字节不是零,则返回true;如果是零,则返回false     * @exception  EOFException 如果此输入流已经到达末尾。     * @exception  IOException  该流已关闭并且包含的输入流在关闭后不支持读取操作,或者发生另其他I/O错误。     */    public final boolean readBoolean() throws IOException {        //从输入流中读取一个字节        int ch = in.read();        //如果达到输入流末尾,抛出异常        if (ch < 0)            throw new EOFException();        //如果读取的字节不是零,则返回true;如果是零,则返回false        return (ch != 0);    }    /**     * 参考DataInput.readByte方法的介绍。     *      * 以下是DataInput.readByte方法的介绍:     *      * 从输入流中读取并返回一个输入字节。     */    public final byte readByte() throws IOException {        int ch = in.read();        if (ch < 0)            throw new EOFException();        return (byte)(ch);    }    /**     * 参考DataInput.readUnsignedByte方法的介绍     *      * 下面是DataInput.readUnsignedByte方法的介绍:     *      * 读取一个输入字节,将它左侧补零转变为int类型,并返回结果,所以结果的范围是0到255     */    public final int readUnsignedByte() throws IOException {        int ch = in.read();        if (ch < 0)            throw new EOFException();        return ch;    }    /**     * 读取两个输入字节并返回一个short值。设ch1为第一个读取字节,ch2为第二个读取字节。     * 返回的值是:(short)((ch1 << 8) + (ch2 << 0))     *      * 如ch1为0010 0010,ch2为0001 1001,那么ch1<<8为0010 0010 0000 0000,ch2<<0不变,这样(ch1 << 8) + (ch2 << 0)就拼接成了一个完成的值。     *     * @return 读取此输入流的两个字节,将它们解释为一个有符号16位数     */    public final short readShort() throws IOException {        int ch1 = in.read();        int ch2 = in.read();        if ((ch1 | ch2) < 0)            throw new EOFException();        return (short)((ch1 << 8) + (ch2 << 0));    }    /**     * 参考readShort方法。     * 问:readUnsignedShort方法与readShort方法代码完全相同,如何保证readUnsignedShort是无符号的?     *      * @return     此输入流的下两个字节,将它们解释为一个无符号16位整数。     */    public final int readUnsignedShort() throws IOException {        int ch1 = in.read();        int ch2 = in.read();        if ((ch1 | ch2) < 0)            throw new EOFException();        return (ch1 << 8) + (ch2 << 0);    }    /**     * 参考readShort方法。     */    public final char readChar() throws IOException {        int ch1 = in.read();        int ch2 = in.read();        if ((ch1 | ch2) < 0)            throw new EOFException();        return (char)((ch1 << 8) + (ch2 << 0));    }    /**     * 参考readShort方法。     */    public final int readInt() throws IOException {        int ch1 = in.read();        int ch2 = in.read();        int ch3 = in.read();        int ch4 = in.read();        if ((ch1 | ch2 | ch3 | ch4) < 0)            throw new EOFException();        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));    }    private byte readBuffer[] = new byte[8];    /**     * 参考readShort方法。     */    public final long readLong() throws IOException {        readFully(readBuffer, 0, 8);        return (((long)readBuffer[0] << 56) +                ((long)(readBuffer[1] & 255) << 48) +                ((long)(readBuffer[2] & 255) << 40) +                ((long)(readBuffer[3] & 255) << 32) +                ((long)(readBuffer[4] & 255) << 24) +                ((readBuffer[5] & 255) << 16) +                ((readBuffer[6] & 255) <<  8) +                ((readBuffer[7] & 255) <<  0));    }    /**     * 参考DataInput.readFloat方法的介绍     *      * 下面是对DataInput.readFloat方法的介绍     * 读取四个输入字节并返回一个float值。     * 实现这一点的方法是:先使用与readInt方法完全相同的方式构造一个int值,然后使用与Float.intBitsToFloat方法完全相同的方式将此int值转换成一个float值。     */    public final float readFloat() throws IOException {        return Float.intBitsToFloat(readInt());    }    /**     * 参考对DataInput.readDouble方法的介绍     *      * 下面是对DataInput.readDouble方法的介绍     * 读取八个输入字节并返回一个double值。     * 实现这一点的方法是:先使用与readlong方法完全相同的方式构造一个long值,     * 然后使用与Double.longBitsToDouble方法完全相同的方式将此long值转换成一个double值。     */    public final double readDouble() throws IOException {        return Double.longBitsToDouble(readLong());    }    private char lineBuffer[];    /**     * 参考对DataInput.readLine方法的介绍     *      * 下面是对DataInput.readLine方法的介绍     * 从输入流中读取下一文本行。     * 该方法读取连续的字节,将每个字节分别转换成一个字符,直到遇到行结尾符或到达末尾;然后以 String 形式返回读取的字符。     */    @Deprecated    public final String readLine() throws IOException {        //该方法已不建议使用,省略    }    /**     * 参考对DataInput.readUTF方法的介绍。     *      * 下面是对DataInput.readUTF方法的介绍:     * 读入一个已使用UTF-8修改版格式编码的字符串。     * readUTF的常规协定是:该方法读取使用UTF-8修改版格式编码的 Unicode字符串的表示形式;     * 然后以String的形式返回此字符串。     *     * @return     一个Unicode字符串     * @exception  EOFException 如果此输入流在读取所有字节之前到达末尾。     * @exception  IOException 该流已关闭并且包含的输入流在关闭后不支持读取操作,或者发生其他I/O错误。     * @exception  UTFDataFormatException 如果这些字节不表示一个有效的、UTF-8修改版编码的Unicode字符串。     */    public final String readUTF() throws IOException {        return readUTF(this);    }    /**     * 从输入流in中读取用UTF-8修改版格式编码的Unicode字符格式的字符串;然后以String形式返回此字符串。     *      * @param in 数据输入流     */    public final static String readUTF(DataInput in) throws IOException {    //待补充}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
思考
  • readUnsignedShort方法与readShort方法代码完全相同,如何保证readUnsignedShort是无符号的?
DataOutputStream/** * DataOutput接口用于将数据从任意Java基本类型转换为一系列字节,并将这些字节写入二进制流。同时还提供了一个将String转换成UTF-8修改版格式并写入所得到的系列字节的工具。 */public class DataOutputStream extends FilterOutputStream implements DataOutput {    /**     * 到目前为止写入到输出流中的字节数     * 最大值为Integer.MAX_VALUE     */    protected int written;    /**     * writeUTF方法使用的字节数组     */    private byte[] bytearr = null;    /**     * 创建一个新的数据输出流     * written初始值为0     */    public DataOutputStream(OutputStream out) {        super(out);    }    /**     * 增加wirtten的值。最大值为Integer.MAX_VALUE     */    private void incCount(int value) {        int temp = written + value;        //int允许的最大值为Integer.MAX_VALUE,即2147483647,2147483647+1即为负数        if (temp < 0) {            temp = Integer.MAX_VALUE;        }        written = temp;    }    /**     * 将指定字节(参数b的八个低位)写入基础输出流。     */    public synchronized void write(int b) throws IOException {        out.write(b);        //如果没有抛出异常,则计数器written增加 1。        incCount(1);    }    /**     * 将指定byte数组中从偏移量off开始的len个字节写入基础输出流。     * 如果没有抛出异常,则计数器written增加len。     */    public synchronized void write(byte b[], int off, int len)        throws IOException    {        out.write(b, off, len);        incCount(len);    }    /**     * 清空此数据输出流。     * 这迫使所有缓冲的输出字节被写出到流中。     */    public void flush() throws IOException {        out.flush();    }    /**     * 将一个boolean值以1-byte值形式写入基础输出流。     * 值true以值(byte)1的形式被写出;值false以值(byte)0的形式被写出。     * 如果没有抛出异常,则计数器written增加 1。     */    public final void writeBoolean(boolean v) throws IOException {        out.write(v ? 1 : 0);        incCount(1);    }    /**     * 将一个byte值以1-byte值形式写出到基础输出流中。     * 如果没有抛出异常,则计数器written增加1。     */    public final void writeByte(int v) throws IOException {        out.write(v);        incCount(1);    }    /**     * 将一个short值以2-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加2(注:因为short是16位的,占两个字节,所以要加2)。     *      * v >>> 8,如v为0010 0011 0000 1111,那么右移8位后为0010 0011     * 再& 0xFF,结果还是0010 0011,这样就取到了v的高8位。     *      * v >>> 0,结果是0010 0011 0000 1111,再& 0xFF,结果是0000 1111,这样就取到了低8位。     *      * 现在的问题是,传入的参数v是二进制的吗?     */    public final void writeShort(int v) throws IOException {        out.write((v >>> 8) & 0xFF);        out.write((v >>> 0) & 0xFF);        incCount(2);    }    /**     * 将一个char值以2-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加2。(注:注:因为char是16位的)     *      * 参考writeShort()中关于(v >>> 8) & 0xFF的介绍。     */    public final void writeChar(int v) throws IOException {        out.write((v >>> 8) & 0xFF);        out.write((v >>> 0) & 0xFF);        incCount(2);    }    /**     * 将一个int值以4-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加4。(注:int为32位的)     *      * 参考writeShort()中关于(v >>> 8) & 0xFF的介绍。     */    public final void writeInt(int v) throws IOException {        out.write((v >>> 24) & 0xFF);        out.write((v >>> 16) & 0xFF);        out.write((v >>>  8) & 0xFF);        out.write((v >>>  0) & 0xFF);        incCount(4);    }    private byte writeBuffer[] = new byte[8];    /**     * 将一个long值以8-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加8。(注:long是64位的)     *      * 参考writeShort()中关于(v >>> 8) & 0xFF的介绍。     */    public final void writeLong(long v) throws IOException {        writeBuffer[0] = (byte)(v >>> 56);        writeBuffer[1] = (byte)(v >>> 48);        writeBuffer[2] = (byte)(v >>> 40);        writeBuffer[3] = (byte)(v >>> 32);        writeBuffer[4] = (byte)(v >>> 24);        writeBuffer[5] = (byte)(v >>> 16);        writeBuffer[6] = (byte)(v >>>  8);        writeBuffer[7] = (byte)(v >>>  0);        out.write(writeBuffer, 0, 8);        incCount(8);    }    /**     * 使用Float类中的floatToIntBits方法将float参数转换为一个int值,     * 然后将该int值以4-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加4。(注:float是32位的)     */    public final void writeFloat(float v) throws IOException {        writeInt(Float.floatToIntBits(v));    }    /**     * 使用Double类中的doubleToLongBits方法将double参数转换为一个long值,     * 然后将该long值以8-byte值形式写入基础输出流中,先写入高字节。     * 如果没有抛出异常,则计数器written增加8。(注:double是64位的)     */    public final void writeDouble(double v) throws IOException {        writeLong(Double.doubleToLongBits(v));    }    /**     * 将字符串按字节顺序写出到基础输出流中。     * 按顺序写出字符串中每个字符,丢弃其八个高位。     * 如果没有抛出异常,则计数器written增加s的长度。     *      * ???不懂为什么这样做。     */    public final void writeBytes(String s) throws IOException {        int len = s.length();        for (int i = 0 ; i < len ; i++) {            out.write((byte)s.charAt(i));        }        incCount(len);    }    /**     * 将字符串按字符顺序写入基础输出流。     * 通过writeChar方法将每个字符写入数据输出流。     * 如果没有抛出异常,则计数器written增加s长度的两倍。(注:字节数/2=字符串长度=字符个数)     *      * 参考writeShort()中关于(v >>> 8) & 0xFF的介绍。     */    public final void writeChars(String s) throws IOException {        int len = s.length();        for (int i = 0 ; i < len ; i++) {            int v = s.charAt(i);            out.write((v >>> 8) & 0xFF);            out.write((v >>> 0) & 0xFF);        }        incCount(len * 2);    }    /**     * 以与机器无关方式使用UTF-8修改版编码将一个字符串写入基础输出流。     */    public final void writeUTF(String str) throws IOException {        writeUTF(str, this);    }    /**     * 待补充     */    static int writeUTF(String str, DataOutput out) throws IOException {        //待补充    }    /**     * 返回written的当前值,即到目前为止写入此数据输出流的字节数。最大值为Integer.MAX_VALUE。     */    public final int size() {        return written;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
思考
  • writeBytes的实现为什么是那样?
demoimport java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/** * DataInputStream 和 DataOutputStream测试类 */public class DataInputStreamTest {    public static void main(String[] args) {        testDataOutputStream();        testDataInputStream();    }    /**     * DataOutputStream的API测试函数     */    private static void testDataOutputStream() {        try {            File file = new File("dataOutputStream.txt");            DataOutputStream out = new DataOutputStream(new FileOutputStream(file));            out.writeBoolean(true);            out.writeByte(122);            out.writeChar('b');            out.writeShort(123);            out.writeInt(1111);            out.writeLong(1233442L);            out.writeUTF("DataOutputStream");            out.close();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * DataInputStream的API测试函数     */    private static void testDataInputStream() {        try {            File file = new File("dataOutputStream.txt");            DataInputStream in = new DataInputStream(new FileInputStream(file));            System.out.printf("readBoolean():%s\n", in.readBoolean());            System.out.printf("readByte():%s\n", in.readByte());            System.out.printf("readChar():%s\n", in.readChar());            System.out.printf("readShort():%s\n", in.readShort());            System.out.printf("readInt():%s\n", in.readInt());            System.out.printf("readLong():%s\n", in.readLong());            System.out.printf("readUTF():%s\n", in.readUTF());            in.close();        } catch (IOException e) {            e.printStackTrace();        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

执行main方法后,控制台会打印出

readBoolean():truereadByte():122readChar():breadShort():123readInt():1111readLong():1233442readUTF():DataOutputStream
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
总结
  • DataInputStream提供了一系列从二进制流中读取字节,并根据所有Java基本类型数据进行重构的readXXXX方法。同时还提供根据UTF-8修改版格式的数据重构String的工具,即readUTF方法。
  • DataOutputStream提供了一系列将数据从任意Java基本类型转换为一系列字节,并将这些字节写入二进制流的writeXXXX方法。同时还提供了一个将String转换成UTF-8修改版格式并写入所得到的系列字节的工具,即writeUTF方法。

1 个回复

倒序浏览

很不错,受教了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马