【问题标题】:Is this an off-by-one bug in Java 7?这是 Java 7 中的一个错误吗?
【发布时间】:2013-12-17 00:44:53
【问题描述】:

我不知道在哪里寻求有关 Java API 文档和 Java 代码的澄清和确认,所以我在这里做。

FileChannel 的 API 文档中,我发现一个错误 w.r.t。在多个地方提交positionsize

这里只是一个例子。 transferFrom(...) 的 API 文档指出:

“如果给定位置大于文件的当前大小,则不传输任何字节。”

我确认 OpenJDK 代码也包含此代码...

public long transferFrom(ReadableByteChannel src, long position, long count)
    throws IOException
{
    // ...
    if (position > size())
        return 0;
    // ...
}

...在文件FileChannelImpl.java 中与文档一致。

现在,虽然上面的代码 sn-p 和 API 文档看起来相互一致,但我“感觉”上面应该是 '大于或等于' 而不仅仅是 '大于' 因为position 是文件数据的从0 开始的索引,在position == size() 处读取将没有数据返回给调用者! (在position == size() - 1,至少 1 个字节——文件的最后一个字节——可以返回给调用者。)

以下是同一 API 文档页面中的其他一些类似实例:

  1. position(...):“将位置设置为大于文件当前大小的值是合法的,但不会改变文件的大小。” em>(应该是“大于或等于”。)

  2. transferTo(...): “如果给定位置大于文件的当前大小,则不传输任何字节。”(应该是“大于或等于'。)

  3. read(...): “如果给定位置大于文件的当前大小,则不会读取任何字节。”(应该是 '大于或等于'。)

最后,read(...) 返回值的文档部分甚至无法与文档的其余部分保持一致。它是这样说的:

read(...)

返回:

读取的字节数,可能为零,如果给定位置大于或等于文件的当前大小,则为 -1

所以,在这个唯一的例子中,我确实看到他们提到了正确的事情。

总的来说,我不知道该怎么做。如果我今天编写与本文档匹配的代码,那么未来 Java 中的错误修复(代码或文档)将使我的代码出现错误,也需要我的修复。如果我今天自己做正确的事,按照他们今天的样子做,那么我的代码一开始就会出错!

【问题讨论】:

  • 我的建议是进行一些实验并提交错误报告:bugreport.sun.com/bugreport
  • 我在大约 2 周前在那里提交了另一个错误。从守护程序得到确认和错误 ID,表明我的错误已被接受,但是......即使在今天,我也无法在错误数据库中查找此错误 ID 及其当前状态。所以,不确定这些人对提交的错误做了什么。
  • 阅读错误报告给我的印象是它们有点慢(因为它们得到了很多),但如果报告清晰,它们确实会得到它们。如果您提出的问题引起了真正的问题,那么他们似乎会考虑所有修复它所需要的错误是更改一些操作员。

标签: java code-documentation filechannel nio2


【解决方案1】:

这在 javadoc 中可能会更清楚一些,现在在此处进行跟踪:

https://bugs.openjdk.java.net/browse/JDK-8029370

请注意,澄清 javadoc 不应该对 FileChannel 的实现进行任何更改(例如,传输方法返回传输的字节数,因此当位置为 size 或超出 size 时为 0)。

【讨论】:

    【解决方案2】:

    这不是一个单独的错误,因为没有行为问题,对吧?充其量是一个文档问题。这里的文档没有错,也许只是不完整。

    但是我不确定他们是否遗漏了什么。 position == size() 不是特殊情况。这是一种根据定义可以读取 0 个字节的情况。 position > size() 异常:可以读取不到 0 个字节。它需要一个注释。是否抛出异常?或者什么都没有。 read() 不同,因为它必须返回一个字节,所以读取 0 也是例外情况。

    我个人认为您所问的事实意味着文档可能更明确。也不清楚为什么该方法不短路而不是尝试传输 0 字节。但它背后似乎有一个可能的逻辑。

    (或者你的意思是它做了一些没有记录的事情?)

    【讨论】:

    • 肖恩,对您的回答不满意。我正在尝试使用 Java 7 的 FileSystemProvider SPI 编写一个完整的自定义文件系统,所以我需要非常准确地知道我要提供什么语义来让 Java 的当前和未来版本对我的代码感到满意。 [续...]
    • 我认为这是文档和代码的问题。如果代码中包含 >=,那将只是一个文档错误,我可以相信我对 positionsize 处理的内在直觉。但是考虑到即使文档在所有地方都不是完全自洽的,我现在真的很困惑要编写什么样的逻辑才能在今天和明天与未来的 Java 版本/补丁一起工作。我必须积极跟踪这些版本,并禁止我的客户不要应用这个或那个版本的 Java 补丁,这有点糟糕。
    • 对我来说这似乎更像是一个文档问题,例如 transferFrom 说如果位置 > size 则不读取任何字节,但如果 position == size 则也不应该传输任何字节。因此,为什么我只建议 OP 看看它是否可以被破坏,如果可以,请提交错误报告。
    • @Harry 我不是为您编写软件或文档,也不是声称它们是正确或一致的。只是试图帮助解析您正在阅读的内容。但是,什么行为是模棱两可的?即使在position == size() 的情况下,这种行为似乎也是完全指定的,而不是通过你用粗体显示的句子,即使他们这样做会很好。
    猜你喜欢
    • 2016-07-12
    • 2012-09-18
    • 2012-03-25
    • 2010-12-22
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多