大文件读取卡死或内存爆满不是python慢,而是方法错误;应使用with配合生成器流式读取,如for line in f或自定义分块读取,避免read()和readlines()一次性加载全量数据。

大文件读取卡死或内存爆满,根本不是Python慢,是方法错了
GB级文件用 open().read() 或 readlines() 会直接把全部内容加载进内存,10GB文件就占10GB RAM——这不是Python的问题,是你在强迫它当内存搬运工。真正高效的做法是“边读边处理”,靠 with 确保资源安全释放,靠生成器控制每次只加载一行或一块。
用 for line in file 是最简流式读法,但要注意编码和换行符
Python 的文件对象本身就是迭代器,for line in f: 底层按行缓冲,不预加载全文,内存占用稳定在几KB级别。但实际踩坑点不少:
- 默认使用系统编码(Windows是cp1252),读UTF-8带BOM或中文会报
UnicodeDecodeError,必须显式指定encoding='utf-8' - 每行末尾自带
\n(或\r\n),line.strip()比line.rstrip('\n')更安全,避免误删字段里的空格 - 如果文件是固定长度记录(如二进制日志),就不能按行读,得用
f.read(chunk_size)分块
with open('huge.log', encoding='utf-8') as f:
for line in f:
process(line.strip())
自定义生成器处理分块读取,避开 readlines() 的隐形陷阱
readlines() 看似按行,实则会一次性把所有行指针加载进列表,对超长行或百万行小文件依然可能OOM。更可控的方式是手写生成器:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 用
f.readline()单次读一行,比for line in f多一层控制权(比如跳过注释、合并续行) - 用
f.read(size)配合io.BytesIO处理二进制块,适合解析协议包或图像切片 - 别用
list(f)—— 它和readlines()行为一致,只是写法更隐蔽
def read_in_chunks(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while chunk := f.read(chunk_size):
yield chunk
for chunk in read_in_chunks('data.bin'):
parse_binary_chunk(chunk)
逐行处理时,with 不保证原子性,出错要自己管状态
with 只确保文件句柄关闭,不负责业务逻辑的中断恢复。比如处理到第100万行崩溃了,下次得从头再来——除非你手动记 checkpoint:
- 把当前行号写入临时文件,每次启动先读这个偏移量,再用
f.seek(offset)跳转(仅限文本可定位场景) - 对不可 seek 的流(如网络响应、管道),只能靠外部消息队列或数据库记录已处理ID
- 避免在生成器里做耗时I/O(如每行都请求API),这会让整个流水线阻塞;应批量攒批后发请求
真正难的从来不是“怎么读”,而是“断点在哪存、错误怎么绕、下游怎么接”。流式处理的边界,永远在业务逻辑里,不在 with 语句中。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










