read()返回空字符串''即代表EOF,因read()和readline()在EOF时返回''(文本模式)或b''(二进制模式),而readlines()返回[];需用==''判断,不可用None或len()==0,且空行是'\n'而非''。

while 循环读文件时,为什么 read() 返回空字符串就代表 EOF
Python 中 read()、readline() 和 readlines() 在到达文件末尾(EOF)时行为不同:read() 和 readline() 返回空字符串 '',而 readlines() 返回空列表 []。所以用 while 驱动流式读取时,必须依赖 read() 或 readline() 的返回值是否为 '' 来判断终止,不能误判为 None 或检查 len() == 0 —— 它们从不返回 None。
常见错误是写成 while line != None: 或 while line: 却没初始化 line,导致 NameError;或把二进制模式下的 b'' 和文本模式的 '' 混淆。
- 文本模式下,
readline()读到末尾返回''(不是'\n') - 二进制模式下,对应返回
b'',需用while chunk != b'' - 每次调用
read(n)最多读n字节,返回可能少于n,但末尾一定为''或b''
用 while True: + break 是最安全的惯用写法
相比在 while 条件中直接调用读取函数(如 while (line := f.readline()) != ''),显式用 while True: 并在循环体内判断后 break 更易读、更易调试,也避免 walrus 操作符在旧 Python 版本中的兼容问题。
f = open('data.txt', 'r')
while True:
line = f.readline()
if line == '':
break
process(line.strip())
f.close()
注意:必须用 line == ''(而非 not line),因为合法的空行是 '\n',strip() 后才是 '',但 EOF 的 '' 不含换行符 —— 这是区分空行和文件结束的关键。
按块读取大文件时,read(size) 的 size 参数影响内存与性能
处理 GB 级日志或数据文件时,逐行读可能因某一行超长而爆内存;此时应改用固定大小块读取,例如每次 read(8192)。只要返回值为 '',就说明真正到了 EOF。
-
size设太小(如1)会导致系统调用频繁,I/O 效率骤降 -
size设太大(如100_000_000)可能一次性加载远超所需的内容到内存 - 典型值是
8192(一页内存大小)或65536,平衡缓存与吞吐
示例:
with open('big.log', 'rb') as f:
while True:
chunk = f.read(8192)
if chunk == b'':
break
# 处理 chunk,注意它可能是不完整行
handle_binary_chunk(chunk)
别忘了异常和资源清理:用 with 语句比手动 close() 更可靠
裸写 open() + while + close() 有风险:如果循环中抛出异常,close() 就不会执行,文件描述符泄漏。即使加 try/finally,也比不上 with 简洁可靠。
with 保证无论正常退出还是异常中断,文件都会被关闭。配合 while 完全无冲突:
with open('input.txt') as f:
while True:
line = f.readline()
if line == '':
break
print(line.rstrip('\n'))
注意:不要在 with 块外继续使用 f,此时它已处于 closed 状态,再调用 readline() 会抛 ValueError: I/O operation on closed file。
真正容易被忽略的是编码问题——没指定 encoding 参数时,open() 使用平台默认编码(Windows 是 cp1252),读 UTF-8 文件可能解码失败;务必显式写 encoding='utf-8'。

















