Шаг 86.
Python: сборник рецептов.
Файлы и ввод-вывод. Итерирование по записям фиксированного размера

    На этом шаге мы рассмотрим способ решения этой задачи.

Задача

    Вместо того чтобы итерировать по файлу построчно, вы хотите итерировать по коллекции записей фиксированного размера или кусочкам ("chunk").

Решение

    Используйте функции iter() и functools.partial(), чтобы выполнить этот отличный фокус:

from functools import partial 

RECORD_SIZE = 32

with open('somefile.data', 'rb') as f:
    records = iter(partial(f.read, RECORD_SIZE), b'') 
    for r in records:
        .   .   .   .

    Объект records в этом примере является итерируемым; он будет производить кусочки фиксированного размера, пока не будет достигнут конец файла. Однако стоит отметить, что в последнем элементе может быть на несколько байтов меньше, чем ожидается, если размер файла не делится на точную длину размера записи.

Обсуждение

    Малоизвестная возможность функции iter() заключается в том, что она может создать итератор, если вы передадите ей вызываемый объект и пороговое значение. Получившийся итератор просто снова и снова вызывает предоставленный вызываемый объект, пока он не вернет пороговое значение, что приведет к завершению итерирования.

    В вышеприведенном решении functools.partial используется для создания вызываемого объекта, который читает фиксированное количество байтов из файла каждый раз, когда вызывается. Пороговое значение b" - то, что будет возвращено при попытке чтения файла, когда будет достигнут его конец.

    И последнее: в показанном выше решении файл был открыт в бинарном режиме. Для чтений записей фиксированного размера это является наиболее распространенным случаем. В случае же текстовых файлов более распространенным будет построчное чтение (итератор выполняет его по умолчанию).

    На следующем шаге мы рассмотрим чтение бинарных данных в изменяемый буфер.




Предыдущий шаг Содержание Следующий шаг