Почему POSIX API не имеет функции конца файла?

В API POSIX read() возвращает 0, чтобы указать, что достигнут конец файла. Почему нет отдельной функции, которая говорит вам, что read() вернет ноль - не требуя от вас на самом деле позвонить read()?


Причина запроса: так как вам нужно позвонить read() чтобы обнаружить, что он потерпит неудачу, это делает алгоритмы чтения файлов более сложными и, возможно, немного менее эффективными, поскольку им приходится выделять целевой буфер, который может не понадобиться.

Что мы хотели бы сделать...

while ( !eof )
   {
   allocate buffer
   read to buffer
   process buffer
   }

Что мы должны сделать вместо этого...

while ( true )
   {
   allocate buffer
   read to buffer
   if ( eof ) release buffer, break;
   process buffer
   }

Кроме того, похоже, что это поведение распространяется на высокоуровневые API, такие как fread() а также feof() в C - и создает много путаницы о том, как использовать feof() правильно:

2 ответа

Чтобы получить представление о том, почему это может иметь место, следует понимать, что конец потока по своей сути не является постоянной ситуацией. Указатель на чтение файла может находиться в конце, но если в результате операции записи будет добавлено больше данных, последующее чтение будет успешным.

Пример: в Linux при чтении из консоли появляется новая строка с ^D вызовет posix::read() вернуть ноль (указывая "конец файла"). Однако, если программа не завершена, она может продолжить чтение (при условии, что введены дополнительные строки).

Поскольку завершение потока не является постоянной ситуацией, возможно, имеет смысл даже не иметь функцию is_at_end() (POSIX нет). К сожалению, это накладывает дополнительное бремя на программиста (и / или библиотеку-обертку), чтобы элегантно и эффективно справляться с этой сложностью.

Общий случай состоит в том, что программа будет иметь больше нуля байтов ввода. Так что в общем случае программа должна будет выделить буфер. Проще не иметь специального случая для пустого ввода.

Другие вопросы по тегам