线程中io.open的readline函数异常:文件增大但读取空行
文件尾部监听时readline返回空的问题解决
问题原因
你的代码出现这种情况,核心原因有两个:
- 文件对象无法感知外部修改:用
seek(0,2)定位到文件末尾后,文件对象的内部指针停在该位置,外部程序追加内容后,文件对象不会自动更新状态,readline()会直接返回空字符串。 - 缓冲同步问题:外部程序写入时可能使用系统缓冲,内容未立即刷新到磁盘;
os.path.getsize()读取的是磁盘文件大小,但文件对象的缓冲区未同步这个变化。
修正后的代码
下面是调整后的实现,主动检查文件大小变化并同步读取新内容:
import io import os import time with io.open(file_path, 'r', encoding='utf-8') as file: # 初始化当前指针位置到文件末尾 current_pos = file.seek(0, 2) while not self._stop_event.is_set(): # 通过文件描述符获取文件实际大小(比os.path.getsize更可靠) file_size = os.fstat(file.fileno()).st_size if file_size > current_pos: # 移动指针到上次读取的位置,避免重复读取 file.seek(current_pos) # 读取所有新增内容并按行处理 for line in file: print(f"LINE : {line.strip()}") # 更新指针位置到当前文件末尾 current_pos = file.tell() else: print(f"NO NEW CONTENT - FILE SIZE = {file_size}") time.sleep(1)
额外处理:无换行符的写入场景
如果外部程序追加的内容可能没有以换行符结尾,readline()会一直等待换行符导致无法返回。这种情况下可以改用读取全部新增内容再分割:
# 替换读取部分的代码 if file_size > current_pos: file.seek(current_pos) # 读取所有新增内容 new_content = file.read() if new_content: # 按行分割,兼容无结尾换行的情况 for line in new_content.splitlines(): print(f"LINE : {line.strip()}") current_pos = file.tell()
关键优化点
- 使用
os.fstat(file.fileno()).st_size直接通过文件描述符获取大小,避免路径解析和系统缓存带来的不一致。 - 通过对比
current_pos和文件大小,主动触发新内容的读取,而非依赖readline()的被动检测。 - 每次读取后更新指针位置,确保不会重复读取旧内容。
内容的提问来源于stack exchange,提问作者VSSajjan
相关产品推荐
相关产品推荐

