Обработка больших текстовых файлов может показаться сложной задачей. Когда файлы вырастают до гигабайт, попытка загрузить их в память все сразу может привести к сбою программы. Python предлагает несколько стратегий для эффективной обработки таких файлов без истощения памяти или производительности.
Основные преимущества освоения этих техник:
MemoryError).Чтение файла построчно гарантирует, что в любой момент времени в память будет загружена только небольшая часть файла. Вот как это сделать:
with open('large_file.txt', 'r') as file: for line in file: # функция обработки строки файла process(line)
Python рассматривает файловый объект как итератор, буферизуя небольшие фрагменты файла. Вариант использования: отлично подходит для обработки журналов логов, CSV-файлов или обычного текста.
Для просмотра определенного количества строк за раз можно использовать itertools.batched(). Код будет выглядеть так:
from itertools import batched # будем перебирать по 25 строк за раз count_package = 25 with open(file_path, "r") as file: for chunk in batched(file, count_str): process_chunk_of_lines(chunk)
Этот подход хорошо работает, если необходимо быстро найти какую-то определенную строку в файле, и не перебирать построчно весь файл. В зависимости от объема файла можно увеличить или уменьшить размер chunk.
Чтение файла фиксированными порциями дает контроль над тем, сколько данных обрабатывается за один раз. Лучше всего подходит для файлов, в которых не требуется построчная обработка.
def read_file_in_chunks(file_path, chunk_size=1024): with open(file_path, 'r') as file: while True: chunk = file.read(chunk_size) if not chunk: break # функция обработки прочитанной порции process(chunk)
Аргумент представленной функции chunk_size необходимо настроить в зависимости от объема памяти OS.
Чтение с буферизацией обеспечивает более высокий уровень оптимизации за счет обработки файлов большими внутренними блоками:
# используем буферизацию 10 MB with open('large_file.txt', 'rb', buffering=10 * 1024 * 1024) as file: for line in file: # функция обработки прочитанной порции process(line)
Подход "Memory mapping" немного сложнее, чем типичный файловый ввод-вывод, но позволяет Python обрабатывать файл как массив байтов непосредственно в памяти. Этот подход используют для чтения огромных файлов к которым требуется произвольный доступ.
from mmap import mmap with open('large_file.txt', 'r') as file: with mmap(file.fileno(), length=0, access=mmap.ACCESS_READ) as mm: for line in mm: # функция обработки прочитанной порции process(line.decode('utf-8'))
Подход Memory mapping работает в 5 раз быстрее по сравнению с обычным подходом чтения файла. Обратите внимание, что улучшение производительности будет еще больше при чтении особенно больших файлов.
Генераторы в python позволяют обрабатывать данные лениво, загружая только то, что необходимо. Пример ниже не показывает всей мощи генераторов и сравним с первым примером.
def generate_lines(file_path): with open(file_path, 'r') as file: for line in file: yield line for line in generate_lines('large_file.txt'): # функция обработки прочитанной строки process(line)
Для того, что бы увидеть, как создаются конвейеры данных при помощи генераторов, смотрите материал "Обработка больших данных при помощи генераторов Python"