for line in file 是最安全的增量读取方式,它按行缓冲读取、不加载全文件,适合 gb 级文本;需显式指定 encoding 防 unicodedecodeerror,用 rstrip("\r\n") 精准去换行符。

用 open() 配合 for line in file 是最安全的增量读取方式
Python 的内置 open() 返回的文件对象是迭代器,for line in file 不会一次性把整个文件加载进内存,而是按行缓冲读取(默认 8KB 缓冲区),适合处理 GB 级文本文件。
常见错误是先用 file.readlines() 或 list(file),这会强制把所有行转成列表,内存直接爆掉。
- ✅ 正确写法:
with open("huge.log", "r", encoding="utf-8") as f: for line in f: process(line.strip()) - ⚠️ 注意编码:大文件若含中文或特殊字符,必须显式指定
encoding,否则可能抛UnicodeDecodeError - ⚠️ 行末换行符:每行自带
\n或\r\n,用line.rstrip("\r\n")比strip()更精准,避免误删有效空格
需要跳过头部或按块读取时,用 itertools.islice() 和 read(size)
如果任务不是“逐行”,而是“跳过前 N 行”或“每次读 M 字节”,直接操作文件指针更可控,避免全量加载。
itertools.islice() 可以在不消耗前面内容的前提下切片迭代器;read(size) 则绕过行边界,按字节读取——适合日志截断、二进制混合文本等场景。
- 跳过前 100 行:
from itertools import islice with open("data.txt") as f: for line in islice(f, 100, None): handle(line) - 每次读 64KB 块:
with open("binary_mixed.txt", "rb") as f: while True: chunk = f.read(65536) # 64KB if not chunk: break parse_chunk(chunk) - ⚠️
read(size)在文本模式下可能在 UTF-8 多字节字符中间截断,导致解码失败 → 必须用"rb"模式 + 自行处理编码,或改用codecs.getreader("utf-8")(f)
逐块读取时如何保证 UTF-8 字符不被截断?
用 read(size) 读文本时,若刚好卡在 UTF-8 多字节字符中间(比如 3 字节汉字只读了前 2 字节),后续 decode() 会报 UnicodeDecodeError: invalid continuation byte。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
解决思路是“多读一点 + 安全截断”:先读略大于目标大小的块,再从末尾向前找最后一个完整字符边界。
- 推荐做法:用
io.TextIOWrapper包装二进制流,并设置newline=""和合理buffering,让 Python 自动处理字符边界import io with open("big_utf8.txt", "rb") as f: wrapper = io.TextIOWrapper(f, encoding="utf-8", newline="", line_buffering=False) wrapper._CHUNK_SIZE = 65536 # 实际需继承重写,但通常直接 for line in wrapper 更稳 - 更稳妥的实操:坚持用
for line in file,它内部已处理好字符边界;只有在必须按字节控制(如网络流、内存映射)时才手动处理截断逻辑
用 mmap 读超大文件时要注意平台和修改风险
mmap 把文件映射到内存地址空间,看似“不占 Python 堆内存”,但实际仍占用虚拟内存,且在 Windows 上对大于 2GB 的文件支持不稳定,Linux 下也受 RLIMIT_AS 限制。
更重要的是:mmap 映射区域可被意外修改(比如误写 mm[0] = 65),导致原文件损坏——除非明确需要随机访问+写入,否则纯读取没必要上 mmap。
- 仅读取场景,比
mmap更轻量的选择:with open("10GB.log", "r", buffering=8192) as f: for line in f: ... - 真要用
mmap,务必加access=mmap.ACCESS_READ锁死写权限import mmap with open("huge.bin", "rb") as f: with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm: # 然后用 mm.find(b"\n") 手动切行 - ⚠️
mmap不兼容with open(...).readlines()这类方法,必须用切片或find()手动解析,开发成本高
逐行迭代是最常用也最容易踩坑的路径——看似简单,但编码、换行符、缓冲区大小、异常恢复这些细节,往往在处理第 3 个不同来源的大文件时才暴露。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










