DataInputStream 继承了 FilterInputStream 类,同时实现了 DataInput 接口。
DataInput 接口提供了一些方法,而在 DataInputStream 中对这些方法进行了实现。
直接来看 DataInputStream 的源码即可。
属性
从父类 FilterInputStream 继承的流对象 in 。
构造函数
使用指定的底层 InputStream 创建一个 DataInputStream。
public DataInputStream(InputStream in) {
super(in);
}
方法
read(byte b[])
// 调用输入流自己的read方法,本类未进行修饰
// 从输入流中读取一定数量的字节,放于字节数组b中,从0下标位置开始存放,最多将b数组存满
public final int read(byte b[]) throws IOException {
return in.read(b, 0, b.length);
}
read(byte b[], int off, int len)
// 调用了输入流自己的read方法,本类未进行修饰
public final int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
readFully
从输入流中读取一些字节,并将它们存储在缓冲区数组 b 中。读取的字节数等于 b 的长度。在出现以下条件之一以前,此方法将一直阻塞:
- 输入数据的 b.length 个字节是可用的,在这种情况下,正常返回。
- 检测到文件末尾,在这种情况下,抛出 EOFException。
- 发生 I/O 错误,在这种情况下,将抛出 IOException,而不是 EOFException。
public final void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
public final void readFully(byte b[], int off, int len) throws IOException {
// 如果需要读取的个数len小于0,抛出范围异常
if (len < 0)
throw new IndexOutOfBoundsException();
// 定义累加计数的n
int n = 0;
// n小于目标个数就继续循环读取,直到n=len为止
while (n < len) {
// 调用输入流自身的read方法来进行读取,直到读够对应的字节数
int count = in.read(b, off + n, len - n);
if (count < 0)
// 读不到字节了,抛出EOF异常
throw new EOFException();
// 累加
n += count;
}
}
skipBytes(int n)
试图在输入流中跳过数据的 n 个字节,并丢弃跳过的字节。不过,可以跳过更少的字节数,该字节数甚至可以为零。这可能由很多情况引起;在已经跳过 n 个字节前到达文件末尾只是其中的一种可能。此方法从不抛出 EOFException。返回实际跳过的字节数。
public final int skipBytes(int n) throws IOException {
int total = 0;
int cur = 0;
while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
total += cur;
}
return total;
}
readBoolean()
读取一个输入字节,如果该字节不是零,则返回 true,如果是零,则返回 false。此方法适用于读取用接口 DataOutput 的 writeBoolean 方法写入的字节。
public final boolean readBoolean() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
readByte()
读取并返回一个输入字节。该字节被看作是 -128 到 127(包含)范围内的一个有符号值。此方法适用于读取用接口 DataOutput 的 writeByte 方法写入的字节。
public final byte readByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
readUnsignedByte()
读取一个输入字节,将它左侧补零 (zero-extend) 转变为 int 类型,并返回结果,所以结果的范围是 0 到 255。如果接口 DataOutput 的 writeByte 方法的参数是 0 到 255 之间的值,则此方法适用于读取用 writeByte 写入的字节。
public final int readUnsignedByte() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return ch;
}
readShort()
读取两个输入字节并返回一个 short 值。设 a 为第一个读取字节, b 为第二个读取字节。此方法适用于读取用接口 DataOutput 的 writeShort 方法写入的字节。
public final short readShort() throws IOException {
// ch1为第一个字节,ch2为第二个字节
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
// 高位左移8位和低位8位相加
return (short)((ch1 << 8) + (ch2 << 0));
}
readUnsignedShort()
读取两个输入字节,并返回 0 到 65535 范围内的一个 int 值。
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);
}
readChar()
读取两个输入字节并返回一个 char 值。
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));
}
readInt()
读取四个输入字节并返回一个 int 值。
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));
}
readLong()
读取八个输入字节并返回一个 long 值。
private byte readBuffer[] = new byte[8];
public final long readLong() throws IOException {
// 读取完整的8个字节
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));
}
readFloat()
读取四个输入字节并返回一个 float 值。实现这一点的方法是:先使用与 readInt 方法完全相同的方式构造一个 int 值,然后使用与 Float.intBitsToFloat 方法完全相同的方式将此 int 值转换成一个 float 值。
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
readDouble()
读取八个输入字节并返回一个 double 值。实现这一点的方法是:先使用与 readlong 方法完全相同的方式构造一个 long 值,然后使用与 Double.longBitsToDouble 方法完全相同的方式将此 long 值转换成一个 double 值。
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
readUTF
读入一个已使用 UTF-8 修改版格式编码的字符串。
public final String readUTF() throws IOException {
return readUTF(this);
}
public final static String readUTF(DataInput in) throws IOException {
int utflen = in.readUnsignedShort();
byte[] bytearr = null;
char[] chararr = null;
if (in instanceof DataInputStream) {
DataInputStream dis = (DataInputStream)in;
if (dis.bytearr.length < utflen){
dis.bytearr = new byte[utflen*2];
dis.chararr = new char[utflen*2];
}
chararr = dis.chararr;
bytearr = dis.bytearr;
} else {
bytearr = new byte[utflen];
chararr = new char[utflen];
}
int c, char2, char3;
int count = 0;
int chararr_count=0;
in.readFully(bytearr, 0, utflen);
while (count < utflen) {
c = (int) bytearr[count] & 0xff;
if (c > 127) break;
count++;
chararr[chararr_count++]=(char)c;
}
while (count < utflen) {
c = (int) bytearr[count] & 0xff;
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
/* 0xxxxxxx*/
count++;
chararr[chararr_count++]=(char)c;
break;
case 12: case 13:
/* 110x xxxx 10xx xxxx*/
count += 2;
if (count > utflen)
throw new UTFDataFormatException(
"malformed input: partial character at end");
char2 = (int) bytearr[count-1];
if ((char2 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + count);
chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
(char2 & 0x3F));
break;
case 14:
/* 1110 xxxx 10xx xxxx 10xx xxxx */
count += 3;
if (count > utflen)
throw new UTFDataFormatException(
"malformed input: partial character at end");
char2 = (int) bytearr[count-2];
char3 = (int) bytearr[count-1];
if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
throw new UTFDataFormatException(
"malformed input around byte " + (count-1));
chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
default:
/* 10xx xxxx, 1111 xxxx */
throw new UTFDataFormatException(
"malformed input around byte " + count);
}
}
// The number of chars produced may be less than utflen
return new String(chararr, 0, chararr_count);
}