用open()配合for循环逐行迭代是最稳妥方式,因文件对象是迭代器,按需读取缓冲块并逐行yield,内存恒定;须指定encoding防unicodedecodeerror,生产环境推荐with语句确保关闭。

用 open() 配合 for 循环是最稳妥的起点
Python 默认的文件迭代器在读取大文件时内存友好,它不会一次性把整个文件加载进内存,而是按需读取缓冲块并逐行 yield。只要你不调用 readlines() 或 read(),就不会爆内存。
- ✅ 正确写法:
for line in open('big.log', 'r', encoding='utf-8'): - ⚠️ 注意:必须显式指定
encoding,否则遇到二进制混杂或编码异常会直接抛UnicodeDecodeError - ⚠️ 文件未关闭?虽然 CPython 通常能及时回收,但生产环境建议用
with包裹
遇到 UnicodeDecodeError 怎么跳过坏字节
超大日志或爬虫 dump 文件常含非法字节(比如截断的 UTF-8 序列),默认 open() 会中断整个读取流程。不能靠 try/except 包裹整行循环——那太慢,且无法继续推进文件指针。
- ✅ 推荐方案:用
errors='ignore'或errors='replace'参数,例如:open('data.bin', 'r', encoding='utf-8', errors='ignore') - ❌ 不要用
errors='surrogateescape'后再手动 decode —— 它保留原始字节但后续处理复杂,对纯文本解析无必要 - ? 如果需定位损坏位置,可先用
rb模式读 chunk,用bytes.decode(errors='backslashreplace')辅助调试
buffering=8192 会影响逐行读取速度吗
默认 buffering=-1 表示使用系统默认缓冲区(通常是 8KB),这对逐行读取已足够。手动设成 8192 不会提速,反而可能因过度切分导致频繁 syscalls;设太大(如 1024*1024)则可能卡住——因为 readline() 依赖换行符触发返回,缓冲区里没遇到 \n 就一直等。
- ✅ 大多数场景保持默认即可
- ⚠️ 只有在明确知道行极长(>1MB)、且磁盘 I/O 是瓶颈时,才考虑增大
buffering并配合io.BufferedReader+readline() - ? 验证方法:用
timeit对比不同 buffering 下 10 万行的耗时,差异通常
需要解析 CSV 或 JSONL?别自己 split(',') 或 json.loads() 逐行硬刚
看似“逐行”处理,但如果每行是结构化数据,手写解析容易漏转义、嵌套、编码边界,还拖慢速度。标准库和成熟包做了大量优化。
- ✅ CSV:用
csv.reader(f),它内部已适配流式读取,支持quoting、escapechar等,且不缓存整列 - ✅ JSONL(每行一个 JSON):用
json.loads(line)是安全的,但推荐ijson.parse()或jsonstream处理超长单行 JSON - ⚠️ 切忌:把整行
line.strip().split('|')用于不定长字段或含分隔符内容——这会在 GB 文件中悄悄吃掉数据
open() 参数干净,再谈优化。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











