Количество прочитанных данных () syscall фактически прочитает - PullRequest
0 голосов
/ 27 мая 2018

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

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

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

Страница руководства в моей системе говорит:

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

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

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

r = read(fd, buf, n);

, обычно нечего получить, если предположить, что если r больше 0, оно должно быть точно n.Ваш код должен уметь обрабатывать случай r < n, поэтому он будет вести себя правильно, когда он почти в конце файла, поэтому, если вы не хотите иметь два разных пути кода (один для «нормального» чтения и один дляПоследнее чтение), вы могли бы также написать один фрагмент кода, который может обрабатывать случай r < n, и позволить ему работать все время.

(Также, как напоминает Zan Lynx в комментарии, некод не должен заметить, что r < n, и сделать вывод, что скоро появится конец файла. Дождитесь r == 0, прежде чем решить, что вы в конце файла.)

0 голосов
/ 27 мая 2018

Вы могли бы прочитать его со справочной страницы самостоятельно:

В Linux read() (и аналогичные системные вызовы) будет передавать не более 0x7ffff000 (2,147,479,552) байтов, возвращая количество фактически переданных байтов.(Это справедливо как для 32-разрядных, так и для 64-разрядных систем.)

Таким образом, даже если у вас достаточно ОЗУ и т. Д., Вы не сможете прочитать полноразмерный образ DVD за один раз.- однако, это не было бы нормальным делом также;для доступа к таким большим файлам лучше было бы mmap.


Кроме этого, может быть доставлен сигнал, который может вызвать выход с помощью EINTR и неопределенное содержимое буфера.

ОШИБКИ

[...]

  • EINTR Вызов был прерван сигналом, прежде чем какие-либо данные были прочитаны;см. сигнал (7).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...