Это ошибка off-by-one в Java 7?

я не знаю, где искать разъяснения и подтверждения по документации Java API и Java-коду, поэтому я делаю это здесь.

в документации по API для FileChannel, я нахожу ошибки off-by-one w.r.т. подать position и файл size в нескольких местах, чем один.

вот только один пример. Документация API для transferFrom(...) гласит:

"если данная позиция больше чем текущий файл в размере тогда байты не передаются."

я подтвердил, что код OpenJDK тоже содержит этот код...

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

... в файле FileChannelImpl.java в соответствии с документацией.

теперь, хотя приведенный выше фрагмент кода и документация API кажутся взаимосогласованными, я "чувствую", что выше должно быть 'больше или равно' а не просто 'больше чем', потому что position быть 0-индекс в данных файла, чтение position == size() не будет иметь данных, чтобы вернуться к вызывающему абоненту! (At position == size() - 1 по крайней мере 1 байт-последний байт файла -- может быть возвращено.)

вот некоторые другие подобные экземпляры на той же странице документации API:

  1. position(...): " установка позиции в значение, которое больше текущий размер файла является законным, но не изменяет размер файла." (должно быть "больше или равно".)

  2. transferTo(...): " если данная позиция больше текущий размер файла, то никакие байты не передаются." (должно быть "больше или равно".)

  3. read(...): "если данная позиция больше файла текущий размер, то байты не читаются." (должно быть "больше или равно".)

наконец, раздел документации для возвращаемого значения read(...) не удается оставаться даже самосогласованным с остальной документацией. Вот что в нем говорится:

read(...)

возвращает:

число считанных байтов, возможно, ноль или -1, если заданная позиция is больше или равно текущий размер файла

в целом, я не знаю, что делать со всем этим. Если я напишу свой код сегодня, соответствующий этой документации, то будущее исправление ошибок в Java (код или документация) сделает мой код багги, требуя исправления с моей стороны. Если я сам поступаю правильно сегодня с вещами, как они стоят сегодня, тогда мой код становится багги, чтобы начать с!

2 ответов


Это может быть немного яснее в javadoc и теперь отслеживается здесь:

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

обратите внимание, что уточнение javadoc не должно ничего менять для реализаций FileChannel (например, методы передачи возвращают количество переданных байтов, поэтому это 0, когда позиция имеет размер или за пределами размера).


это не ошибка off-by-one в том, что нет проблем с поведением, верно? В лучшем случае проблема с doc. Документы здесь не ошибаются, может быть, просто не полные.

однако я не уверен, что они что-то упускают. position == size() не является исключительной ситуацией. Это ситуация, когда 0 байт можно прочитать по определению. position > size() является исключительным: может быть прочитано менее 0 байт. Нужна записка. Вызывает ли исключение? Или ничего. read() отличается, так как он должен возвращать байт так наличие 0 для чтения также является исключительным условием.

Я лично думаю, что тот факт, что вы спрашиваете, означает, что документы могут быть более явными. Также не ясно, почему этот метод не делает короткое замыкание, а не пытается передать 0 байтов. Но, похоже, за этим кроется логика.

(или вы имеете в виду, что это что-то не документировано?)