人人都会AI编程

12.6 大文件处理:逐行读取、分块处理、内存优化

更新时间:2026-07-12

处理几百 MB 甚至 GB 级别的文件时,如果直接 f.read() 把整个文件内容读进内存,程序很容易因内存耗尽而崩溃。这一节就讲如何安全、高效地处理大文件。

逐行读取:处理文本文件的首选

当文件是文本格式(如日志、CSV、JSONL),最常见也最简单的做法是逐行读取——每次只把一行加载到内存,处理完就丢弃。

with open('large_file.log', 'r', encoding='utf-8') as f:
    for line in f:
        # 对每一行进行处理,比如提取关键信息
        process(line)
  • for line in f 本身就是一种迭代器,Python 会按缓冲区读取数据,不会一次性加载整个文件。
  • 如果需要保留行号,可以用 enumerate(f, start=1)
  • 对于 CSV 文件,可以直接用 csv.reader 迭代:
import csv
with open('large.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        process(row)

分块读取:控制每次读取的字节数

对于二进制文件(图片、视频)或无法按行分割的文本,可以指定一个固定大小的块,循环读取直到文件末尾。

chunk_size = 1024 * 1024  # 1MB 一块
with open('large_file.bin', 'rb') as f:
    while True:
        chunk = f.read(chunk_size)
        if not chunk:
            break
        process(chunk)
  • 块大小可以根据可用内存和业务需求调整,通常在 4KB~64MB 之间。
  • 适合大文件复制、传输、哈希计算等场景。

利用生成器封装:让代码更整洁

可以把分块或逐行读取的逻辑封装成一个生成器,业务代码只需关心如何处理每一块数据。

def read_in_chunks(file_path, chunk_size=1024*1024):
    with open(file_path, 'rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            yield chunk

for chunk in read_in_chunks('big_data.bin'):
    handle(chunk)

内存优化的额外技巧

  • 及时释放变量:如果文件中有大量字符串或对象累积,用 del 或在循环内复用变量,避免无用的引用。
  • 优先使用迭代器:无论文件还是数据处理,能用迭代器就不用列表,避免在内存中产生中间副本。比如 sum(line.count('error') for line in f) 比先构建列表再求和内存友好得多。
  • 注意编码成本:读取文本时,如果不需要全部字符串内容,可以考虑只保留必要字段,或使用 bytes 操作避免解码全部字符(仅在少数场景下适用)。

大文件处理的核心思想就是分而治之:让数据像水一样流过你的程序,而不是把整个池塘装进杯子里。养成逐行或分块处理的习惯,就能从容应对绝大部分大数据量场景,而不用担心内存溢出。