什么时候DataInputStream.skipBytes(n)不跳过n个字节?

时间:2020-03-05 18:49:53  来源:igfitidea点击:

Sun DataInput.skipBytes文档指出,"它试图从输入流中跳过n个字节的数据,丢弃跳过的字节。但是,它可能会跳过一些较小的字节,可能为零。这可能是由于多种条件中的任何一种;在跳过n个字节之前到达文件末尾只是一种可能。"

  • 除了到达文件末尾以外,为什么skipBytes()不能跳过正确的字节数? (我正在使用的" DataInputStream"将包装" FileInputStream"或者" PipedInputStream"。)
  • 如果我肯定要跳过n个字节并抛出EOFException,如果这导致我转到文件末尾,是否应该使用readFully()并忽略结果字节数组?或者,还有更好的方法?

解决方案

回答

1)可能没有太多的数据可供读取(管道的另一端可能尚未发送那么多的数据),并且实现类可能是非阻塞的(即,它将仅返回其能返回的值,而不是等待足够的数据来满足请求)。

我不知道是否有任何实现实际上以这种方式运行,但是接口被设计为允许这样做。

另一种选择是简单地在读取过程中部分关闭文件。

2)或者readFully()(它将始终等待足够的输入,否则将失败)或者在循环中调用skipBytes()。我认为前者可能会更好,除非阵列真的很大。

回答

乔什·布洛赫(Josh Bloch)最近对此进行了宣传。一致的是,不保证InputStream.read读取尽可能多的字节。但是,它作为API方法是毫无意义的。 InputStream可能还应该具有readFully。

回答

事实证明,readFully()增加了比我愿意忍受的性能开销更多的开销。

最后,我妥协了:我调用一次skipBytes(),如果返回的字节数少于正确的字节数,那么我为其余字节调用readFully()。

回答

我今天遇到了这个问题。它正在读取虚拟机上的网络连接,因此我想可能有多种原因导致这种情况的发生。我通过简单地强迫输入流跳过字节直到它跳过了我想要的字节数来解决了它:

int byteOffsetX = someNumber; //n bytes to skip
int nSkipped = 0;

nSkipped = in.skipBytes(byteOffsetX);
while (nSkipped < byteOffsetX) {
    nSkipped = nSkipped + in.skipBytes(byteOffsetX - nSkipped);
}