由java.io.DataInputStream
得到的readInt()
函数如下:
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));
}
在函数中,您可以看到它在(ch1|ch2|ch3|ch4)<0
时抛出EOFException
(文件结束异常)。但是我受到了标准EOF字节为-1的影响。(也就是说,255,0xFF, 0b11111111,或者你喜欢的任何符号…)然而,这个函数只检查是否有任何字节为负。所以…这是怎么回事?
EOF为-1 (int), int为32位。因此255(字节)不等于-1 (int)。
那么readInt()方法在做什么?
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
这些行读取原始字节,作为整型。int型的8位保留给原始字节。由于字节内没有空间来表示NO VALUE,因此使用int范围中的额外位。负位
所以这些行乐观地读取了所有四个字节,这将被组合在一起创建最终的int值。此目标整型值不能与每个字节的整型表示混淆。
if ((ch1 | ch2 | ch3 | ch4) < 0)
是检查所读入的所有四个字节是否存在的有效方法。另一种方法是读取一个字节,检查它,然后读取下一个字节并测试它。对于现代cpu来说,拥有一个分支比拥有四个分支更有效率。
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
if检查失败后,我们知道每个字节的int表示都是正的,因此int中未被字节值(32-8位)使用的额外24位都是零。这样,我们就把比特移动到正确的位置,并把它们组合起来;给出最终值