FileInputStream负跳过

4
我正在尝试了解关于java.io.FileInputStream.skip(n)操作历史的更多信息,当n为负数时。根据InputStream文档

如果n为负,则不跳过任何字节。

似乎Sun的FileInputStream实现曾经抛出IOException,但现在也在Javadoc中记录

如果n为负,则抛出IOException,即使InputStream超类的skip方法在这种情况下什么也不做。

我刚试过了,发现FileInputStream.skip(-10)实际上返回了-10!它没有抛出异常,甚至没有返回0,而是返回了-10。(我已经尝试过使用来自Sun的Java 1.5.0_22和Java 1.6.0_18)。
这是一个已知的bug吗?为什么它没有被修复,或者为什么文档保持原样?有人能指导我关于这个问题的讨论吗?我找不到任何信息。

也许与文档中的这些行有关: 该方法可能会跳过比支持文件中剩余的字节数更多的字节。这不会产生异常,跳过的字节数可能包括超出支持文件EOF的某些字节。在跳过结尾后尝试从流中读取将导致-1表示文件结束。 我在 scrapbook 中尝试了它,并得到了带有适当消息的 IOException。 顺便说一句,没想到在这里遇到你 :) - Gabriel Ščerbák
我正在尝试使用jdk1.6.0_13进行测试。 - Gabriel Ščerbák
1
如果InputStream文档明确指出“如果n为负,则不跳过任何字节”,但FileInputStream却跳过了,那么看起来像是一个bug。可能是文档或实现的问题。 - user253751
1个回答

1

SocketInputStream 的实际实现给出了答案:

  public long skip(long numbytes) throws IOException {
        if (numbytes <= 0) {
            return 0;
        }
  ...
  }

编辑:抱歉,我检查了错误的类FileInputStream的实现是本地的,这是在openjdk7中的实现

if ((cur = IO_Lseek(fd, (jlong)0, (jint)SEEK_CUR)) == -1) {
        JNU_ThrowIOExceptionWithLastError(env, "Seek error");
    } else if ((end = IO_Lseek(fd, toSkip, (jint)SEEK_CUR)) == -1) {
        JNU_ThrowIOExceptionWithLastError(env, "Seek error");
    }
    return (end - cur);

问题涉及FileInputStream。 - user207421
1
@Stacker,感谢你抽出时间查找openjdk7中的实现。我也很好奇,但我更感兴趣的是它为什么会以这种方式工作。我的意思是,如果文档说负值应该引起IOException,那么是否存在任何允许负值的原因? - Peter Štibraný
@Peter Štibraný http://linux.die.net/man/2/lseek - 即使系统调用没有说明有效范围,也许在操作系统中,如果您可以在EOF之后寻找,则可能也可以在文件开头之前寻找。但是我没有时间查看Linux内核。 - stacker
1
不要费心于低级别的事情。我真的很感兴趣为什么Java实现在Javadoc注释中没有抛出IOException。无论如何,谢谢 :-) (我现在已经在Sun/Oracle数据库中填写了错误报告) - Peter Štibraný

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接