不一致的BufferedInputStream read(byte [])行为

时间:2012-07-10 05:41:47

标签: java bufferedinputstream

我对BufferedInputStream.read(byte [])的理解是读取操作从pos开始,并且读取直到字节数组已满或流结束。

我在BufferedInputStream上调用下面的readInt方法。

public class XDRInputStream {

private InputStream stream;

private byte[] buffer4 = new byte[4]; // fixed size buffers
private byte[] buffer8 = new byte[8];

public XDRInputStream(InputStream stream) {
    this.stream = stream;
}

public InputStream getInternalStream() {
    return stream;
}

public int readInt() throws IOException {
    if (stream.read(buffer4) != -1) {
        return ((buffer4[0] & 0xFF) << 24)
             | ((buffer4[1] & 0xFF) << 16)
             | ((buffer4[2] & 0xFF) << 8)
             | ((buffer4[3] & 0xFF));
    } else {
        throw new EOFException("End of stream");
    }
}

当我在Eclipse调试器中跟踪执行时,stream.read(buffer4)调用 - 无论起始位置值 - 通常会导致pos的值设置为4,而读取的4个字节是前4个字节输入流。 read(byte [])调用是否在某些情况下悄悄地重置流,如果是,何时?这似乎是预期的行为(这不是我的代码),当它以这种方式运行时,程序运行正常。

我遇到的问题是,有时候,只有在Windows上,并且只有当输入流包含特定内容时(在这种情况下由于丢弃的套接字上游产生的错误消息),这种情况下的重置不会发生意图导致该方法从流中的错误位置读取并返回不正确的值。

我们在Solaris上使用相同的代码,虽然我没有在此平台上完成调试器步骤,但在Solaris下,程序运行良好,并且我尝试修复的错误不会发生。我不知道有哪些特定于平台的问题?

感谢。

2 个答案:

答案 0 :(得分:2)

根据经验,您不能依赖于一次性从流中读取整个数组。 如果查看docs,您会看到read(byte[])的返回值是读取的字节数,可能是整个数组长度或更短。如果还没有数据,甚至是0。并且它非常典型(并且可能依赖于操作系统)读取少于整个数组。

所以你必须确保你实际上读了4个字节。

答案 1 :(得分:1)

  

我对BufferedInputStream.read(byte [])的理解是读取操作从pos开始,并且读取直到字节数组已满或流结束。

您的理解不正确。

你的理解与Javadoc完全矛盾,Javadoc表示如果必要,它会阻塞,直到至少有一个字节可用,读取可用的内容,并返回读取的字节数,如果读取EOS则返回-1代替。