DataInputStream.skipBytes(n) 什么时候不能跳过n个字节?
题
这 DataInput.skipBytes 的 Sun 文档 声明它“尝试从输入流中跳过 n 个字节的数据,并丢弃跳过的字节。但是,它可能会跳过一些较小数量的字节,可能为零。这可能是由多种情况中的任何一种造成的;在跳过 n 个字节之前到达文件末尾只是一种可能性。”
除了到达文件末尾之外,为什么可能
skipBytes()
没有跳过正确的字节数?(这DataInputStream
我正在使用要么包装一个FileInputStream
或一个PipedInputStream
.)如果我确实想跳过 n 个字节并抛出一个
EOFException
如果这导致我转到文件末尾,我应该使用readFully()
并忽略结果字节数组?或者,还有更好的方法?
解决方案
1)可能没有那么多数据可供读取(管道的另一端可能还没有发送那么多数据),并且实现类可能是非阻塞的(即它只会返回它能返回的内容,而不是等待足够的数据来满足请求)。
然而,我不知道是否有任何实现实际上以这种方式运行,但接口的设计允许这样做。
另一种选择是文件在读取过程中被关闭。
2) 要么readFully()(总是等待足够的输入,否则失败),要么循环调用skipBytes()。我认为前者可能更好,除非数组确实很大。
其他提示
我今天遇到了这个问题。它正在读取虚拟机上的网络连接,因此我想发生这种情况可能有多种原因。我通过简单地强制输入流跳过字节来解决这个问题,直到它跳过了我想要的字节数:
int byteOffsetX = someNumber; //n bytes to skip
int nSkipped = 0;
nSkipped = in.skipBytes(byteOffsetX);
while (nSkipped < byteOffsetX) {
nSkipped = nSkipped + in.skipBytes(byteOffsetX - nSkipped);
}
乔什·布洛赫(Josh Bloch)最近公开了这一点。它的一致性在于,InputStream.read 不保证读取尽可能多的字节。然而,它作为 API 方法是完全没有意义的。InputStream 应该也有 readFully。
事实证明, readFully() 增加的性能开销超出了我愿意忍受的范围。
最终我妥协了:我调用了一次skipBytes(),如果返回的字节数少于正确的字节数,我会调用readFully()来获取剩余的字节。