用while循环分批读取大文件需避免一次性加载,核心是按行或按字节块处理:按行推荐readline()或iter+next;按字节需处理断行和UTF-8截断,二进制模式更稳妥,务必用with确保关闭。

用 while 循环分批读取大文件,核心是避免一次性加载整个文件到内存,而是按块(如按行或按字节)逐步处理。关键在于控制读取节奏,配合文件对象的迭代或 read() 方法。
按行读取:最常用且安全的方式
适合文本文件,尤其是日志、CSV 等以行为单位的场景。Python 文件对象本身支持迭代,for line in f: 本质就是逐行读取,但若坚持用 while,可搭配 next() 或手动判断:
- 用
iter()和next()构造可控的 while 循环:
with open('big.log', 'r', encoding='utf-8') as f:
line_iter = iter(f) # 获取迭代器
while True:
try:
line = next(line_iter)
# 处理单行,例如:print(line.strip())
except StopIteration:
break- 更简洁写法(不推荐新手直接用,但更贴近“while 控制流”):
with open('big.log', 'r', encoding='utf-8') as f:
while (line := f.readline()): # Python 3.8+ 海象运算符
# 处理 line,注意 line 包含换行符\n
process(line)按固定字节数读取:适合二进制或超大纯文本
当行长度差异极大(如某些日志无换行)、或需严格控内存时,可用 read(size) 分块读取:
- 每次读取最多
n字节,返回字符串(文本模式)或 bytes(二进制模式) - 需自行处理“块内断行”问题:最后一行可能不完整,建议在块末尾保留未结束的行,拼到下一块
- 示例(文本模式,缓冲区 8192 字节):
buffer = ''
with open('huge.txt', 'r', encoding='utf-8') as f:
while True:
chunk = f.read(8192)
if not chunk:
break
buffer += chunk
lines = buffer.split('\n')
# 保留最后一行(可能不完整),其余全处理
buffer = lines[-1]
for line in lines[:-1]:
process(line)循环结束后别忘了处理残留的 buffer(如果非空,说明最后一行没换行符)。
配合生成器封装:提升复用性和可读性
把分批逻辑封装成生成器,让 while 调用更干净:
def read_in_chunks(file_obj, chunk_size=8192):
while True:
data = file_obj.read(chunk_size)
if not data:
break
yield data
<h1>使用</h1><p>with open('data.bin', 'rb') as f:
chunk_iter = read_in_chunks(f, 4096)
while True:
try:
chunk = next(chunk_iter)</p><h1>处理 chunk,例如解码、解析协议</h1><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;"> except StopIteration:
break</code></pre>注意事项和避坑点
-
别用
while f.read():会一次性读完全部内容,失去分批意义 -
文本模式下慎用
read(n)处理 UTF-8:可能在多字节字符中间截断,导致解码错误;建议用readline()或增大 chunk_size 避开边界问题 -
二进制模式更稳妥:若原始数据无编码问题(如日志已为 bytes、或自定义协议),优先用
'rb'模式 +read(n) -
关闭文件很重要:务必用
with语句,或手动f.close(),否则资源泄漏

















