"короткое чтение" из файловой системы, когда это может произойти?
Очевидно, что в общем случае системный вызов read (2) может возвращать меньше байтов, чем то, что было предложено для чтения. Однако многие программы предполагают, что при работе с локальными файлами чтение (2) никогда не возвращается меньше, чем было задано (если, конечно, файл короче).
Итак, мой вопрос: на Linux, в каких случаях можно читать (2), возвращать меньше, чем было запрошено, если чтение из открытого файла и EOF не встречается, а прочитанная сумма составляет не более нескольких килобайт?
Некоторые предположения:
- Может ли принятый сигнал прерывать чтение таким образом, но не сделать его неработоспособным?
- Могут ли разные файловые системы влиять на это поведение? Есть что-то особенное в jffs2?
Ответы
Ответ 1
POSIX.1-2008 указывает:
Возвращаемое значение может быть меньше nbyte, если количество оставшихся байтов в файл меньше, чем nbyte, если read() был прерван сигнала, или если файл является трубой или FIFO или специальный файл и имеет меньшее количество чем nbyte байты для чтения.
Дисковые файловые системы обычно используют источники бесперебойного чтения, что означает, что
операция чтения обычно не может быть прервана сигналом. Сеть на основе
файловые системы иногда используют прерывистые чтения, которые могут возвращать частичные данные или данные.
(В случае NFS это настраивается с использованием опции монтирования intr
.)
Иногда они также используют таймауты.
Имейте в виду, что даже/some/произвольный/файл/путь может ссылаться на FIFO или
специальный файл, поэтому то, что вы считали обычным файлом, может и не быть. Поэтому
хорошая практика обработки частичных чтений, даже если они маловероятны.
Ответ 2
Я должен спросить: "Почему вас волнует причина"? Если чтение может вернуть количество байтов меньше запрашиваемой суммы (что, как вы указываете, это, безусловно, может), почему вы не хотите иметь дело с этой ситуацией?
Ответ 3
Принятый сигнал только делает read() неудачным, если он еще не прочитал один байт. В противном случае он вернет частичные данные.
И я думаю, что альтернативные файловые системы действительно могут возвращать короткие чтения в других ситуациях. Например, имеет смысл (для меня), чтобы сетевая файловая система вела себя так же, как сетевой сокет, при коротком чтении (= часто их).
Ответ 4
Если это действительно файл, который вы читаете, вы можете быстро прочитать его как последнее прочитанное до конца файла.
Как бы то ни было, лучше всего вести себя так, как будто ЛЮБОЕ прочитанное может быть короткое чтение. Если то, что вы читаете, является каналом или устройством ввода (stdin), а не файлом, вы можете получить короткое чтение, когда ваш буфер больше, чем тот, который находится во входном буфере.
Ответ 5
Я не уверен, но эта ситуация может возникнуть, когда в ОС не хватает страниц в кеше страниц. Вы можете предположить, что в этом случае вызывается поток flush, но он зависит от эвристики, используемой в планировщике ввода-вывода. Эта ситуация может привести к тому, что чтение вернет меньшее количество байтов.