【问题标题】:FileInputStream negative skipFileInputStream 负跳过
【发布时间】:2012-05-05 06:56:36
【问题描述】:

n 为负数时,我正在尝试查找有关java.io.FileInputStream.skip(n) 操作历史的更多信息。根据InputStream documentation

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

似乎是来自 Sun used to throw IOException 的 FileInputStream 的实现,现在也是 documented in Javadoc

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

我刚试过,发现FileInputStream.skip(-10) 实际上返回了-10!它没有抛出异常,它甚至没有返回 0,它返回了 -10。 (我尝试过使用 Sun 的 Java 1.5.0_22 和 Sun 的 Java 1.6.0_18)。

这是一个已知的错误吗?为什么它没有被修复,或者为什么文档保持原样?有人可以指出我对这个问题的一些讨论吗?我什么都找不到。

【问题讨论】:

  • 也许它与文档中的这些行有关:此方法可能会跳过比支持文件中剩余的字节更多的字节。这不会产生异常,并且跳过的字节数可能包括超出后备文件 EOF 的一些字节数。在跳过结尾后尝试从流中读取将导致 -1 指示文件的结尾。我在剪贴簿中尝试过,并且收到带有正确消息的 IOException。顺便提一句。没想到会在这里遇到你:)
  • ...我用 jdk1.6.0_13 试了一下
  • 如果 InputStream 文档明确说“如果 n 为负,则不跳过任何字节”,但 FileInputStream 跳过了,那么它看起来像一个错误。在文档或实现中。

标签: java fileinputstream


【解决方案1】:

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

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

编辑:抱歉,我检查了错误的类 FileInputStreams 实现是原生的,这是 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。
  • @Stacker,感谢您花时间在 openjdk7 中查找实现。我也对它很好奇,但我最感兴趣的是为什么它的工作方式。我的意思是,如果文档说它们应该导致 IOException,是否有任何理由允许负值?
  • @Peter Štibraný linux.die.net/man/2/lseek - 即使系统调用也没有说明有效范围,如果你可以在 EOF 后面寻找它,它可能是操作系统依赖的,它也可以在文件开头之前寻找。但我没有时间研究 linux 内核。
  • 不要为低级的东西烦恼。我对Java 实现不抛出 Javadoc 注释中记录的 IOException 的原因非常感兴趣。无论如何,谢谢 :-)(我现在已经在 Sun/Oracle 数据库中填写了错误报告)
猜你喜欢
  • 2015-12-09
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多