Потому что таким образом он может обнаружить EOF
, не зная, насколько велик файл. Все, что нужно сделать, это просто попытаться прочитать, и если чтение короткое (но не ошибка), значит, вы достигли конца файла.
Это отражает функциональность системного вызова read
, который обычно завершается вызовом файлового ввода-вывода (win32 может вызвать ReadFile
, но я считаю, что функциональность аналогична).
Из справочной страницы read
«ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ» (выделение добавлено):
В случае успеха количество прочитанных байтов
возвращается (ноль указывает на конец
файл) , а позиция файла
продвинутый этим числом. Это не
ошибка, если это число меньше
количество запрошенных байтов; этот
может случиться, например, потому что меньше
байты на самом деле доступны прямо сейчас
(возможно, потому что мы были близки к
конец файла, или потому что мы читаем
из трубы или из терминала), или
потому что чтение () было прервано
сигнал. При ошибке возвращается -1 и
errno установлен соответствующим образом. В этом
случай, если это не указано,
положение файла (если есть) изменяется.
Кстати: хороший способ написать то, что вы хотели, будет выглядеть так:
T something;
while(file.read(something, sizeof(something))) {
// process your 'something'
}
это работает, потому что file.read
(как и многие члены iostream) возвращают ссылку на сам iostream. Все они имеют перегруженный оператор, чтобы позволить тестировать состояние потока. Аналогично чтению из std::cin
, while(std::cin >> x) { ... }
также работает.
РЕДАКТИРОВАТЬ: вы должны знать, что тестирование против сбоя может быть одинаково неправильно по той же причине. Со страницы, на которую вы ссылаетесь fail()
, возвращается, если предыдущая операция завершилась неудачно. Это означает, что вам нужно выполнить чтение или другую соответствующую операцию перед тестированием.