Ответ 1
Вы не думаете с вашей кожей змеи на... Python не C.
Во-первых, обзор:
- st = f.read() читает EOF, или если он открыт как двоичный, до последнего байта;
- st = f.read(n) пытается читать
n
байты и не более чемn
bytes; - 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
bytes?
- EOF, безусловно, является общей причиной;
- Сетевой сокет может отключиться при чтении, но остается открытым;
- Точно
n
байты могут привести к разрыву между логическими многобайтовыми символами (например,\r\n
в текстовом режиме и, я думаю, многобайтовым символом в Юникоде) или некоторой базовой структурой данных, не известной вам; - Файл находится в неблокирующем режиме, и другой процесс начинает обращаться к файлу;
- Временный не-доступ к файлу;
- Основное условие ошибки, потенциально временное, в файле, диске, сети и т.д.
- Программа получила сигнал, но обработчик сигнала проигнорировал его.
Я бы переписал ваш код таким образом:
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