Сообщить об ошибке.

Способы работы с большими файлами в Python

Содержание:

Обработка больших текстовых файлов может показаться сложной задачей. Когда файлы вырастают до гигабайт, попытка загрузить их в память все сразу может привести к сбою программы. 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"

Подход "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"