处理大文件应避免一次性读取,优先采用流式读取:按行迭代(适合文本)、分块读取(二进制或超长行)、生成器封装、内存映射(mmap)随机访问。
处理大文件时,直接用 open().read() 容易内存爆炸。核心思路是:不一次性加载全部内容,改用流式读取、分块处理、按需解析。
对逐行处理的场景(如过滤日志、统计关键词),用 for 循环遍历文件对象最省内存:
readlines() —— 它会把所有行载入内存,即使你只想要前10行with open('access.log') as f:
for line in f: # 每次只加载当前行
if 'ERROR' in line:
print(line.strip())
当文件含超长行(如单行 JSON、DNA 序列)或纯二进制数据(如视频片段提取),需手动控制缓冲区大小:
f.read(chunk_size) 按固定字节数读取,比如 8192 字节(8KB)是常见平衡点with open('data.bin', 'rb') as f:
while True:
chunk = f.read(4096)
if not chunk:
break
process_chunk(chunk) # 自定义处理函数
把文件解析逻辑封装成生成器,既能复用,又保持低内存占用:
yield 就暂停并返回一个值,下次调用再从断点继续def csv_chunk_reader(filepath, chunk_size=1000):
with open(filepath, encoding='utf-8') as f:
reader = csv.reader(f)
buffer = []
for row in reader:
buffer.append(row)
if len(buffer) >= chunk_size:
yield buffer
buffer = []
if buffer:
yield buffer
当需要随机访问大文件某几处(如查找偏移量、校验哈希),mmap 比传统读取更高效:
mmap 把文件“映射”到内存地址空间,操作系统按需加载页,不占实际 RAMimport mmap
with open('huge.bin', 'rb') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# 直接切片访问,像操作 bytes 一样
header = mm[:16]
checksum = mm[-32:]