Вы не думаете, что у вас змеиная шкура ... Python - это не C.
Сначала обзор:
- st = f.read () читает в EOF или, если открыт как двоичный файл, до последнего байта;
- st = f.read (n) пытается прочитать
n
байтов и ни в коем случае не более n
байтов;
- st = f.readline () читает строку за раз, строка заканчивается на \ n или EOF;
- st = f.readlines () использует readline () для чтения всех строк в файле и возвращает список строк.
Если метод чтения файла находится в EOF, он возвращает ''
. Такой же тип теста EOF используется в других «файловых» методах, таких как StringIO, socket.makefile и т. Д. Возврат менее чем n
байтов из f.read(n)
, безусловно, НЕ является диспозитивным тестом для EOF! код может работать в 99,99% случаев, это то время, когда он не работает, и найти его очень сложно. Плюс, это плохая форма Python. Единственное использование для n
в этом случае - это установить верхний предел размер возврата.
По каким причинам файловые методы Python возвращают меньше , чем n
байт?
- EOF, безусловно, распространенная причина;
- Сетевой сокет может тайм-аут при чтении, но остается открытым;
- Точно
n
байтов может привести к разрыву между логическими многобайтовыми символами (такими как \r\n
в текстовом режиме и, я думаю, многобайтовым символом в Unicode) или некоторой базовой структурой данных, которая вам не известна;
- Файл находится в неблокирующем режиме, и другой процесс начинает доступ к файлу;
- Временное отсутствие доступа к файлу;
- Базовое состояние ошибки, потенциально временное, для файла, диска, сети и т. Д.
- Программа получила сигнал, но обработчик сигнала проигнорировал его.
Я бы переписал ваш код следующим образом:
with open(filename,'rb') as f:
while True:
s=f.read(max_size)
if not s: break
# process the data in s...
Или написать генератор :
def blocks(infile, bufsize=1024):
while True:
try:
data=infile.read(bufsize)
if data:
yield data
else:
break
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
break
f=open('somefile','rb')
for block in blocks(f,2**16):
# process a block that COULD be up to 65,536 bytes long