
python标准库不提供“读一行删一行”的内置函数,但可通过外部进度文件记录已处理行号,实现断点续传式文件处理,避免频繁重写文件带来的性能与可靠性问题。
在实际开发中,尤其是处理日志、批量任务或数据导入场景时,常需确保程序意外中断(如断电、崩溃)后能从中断处继续执行,而非从头开始或丢失状态。直接“边读边删行”看似直观,但文件系统本身不支持随机删除某一行——因为文本文件是连续字节流,删除中间一行需重写其后的全部内容,开销大且非原子操作,极易因中断导致文件损坏。
因此,更稳健、专业的做法是分离“状态跟踪”与“数据存储”:保持原始文件只读不变,用独立的轻量级机制(如进度文件)持久化处理位置。以下是推荐实现方案:
✅ 推荐方案:基于行号的断点续传处理
def process_file(filepath, progress_filepath):
# 1. 读取上次处理到的行号(默认为0)
try:
with open(progress_filepath, 'r') as pf:
last_processed = int(pf.read().strip())
except (FileNotFoundError, ValueError):
last_processed = 0
# 2. 逐行读取原文件(使用生成器避免内存爆炸)
with open(filepath, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, start=1):
if line_num <= last_processed:
continue # 跳过已处理行
# 3. 执行业务逻辑(此处仅为示例)
print(f"✅ Processing line {line_num}: {line.rstrip()}")
# your_processing_logic(line)
# 4. 原子化更新进度(写入后立即刷新,降低丢失风险)
with open(progress_filepath, 'w') as pf:
pf.write(str(line_num))
pf.flush() # 确保写入磁盘,非仅缓冲区⚠️ 关键注意事项
- 不要用 readlines() 加载大文件到内存:示例中改用 for line in file 迭代器,内存占用恒定 O(1),适用于 GB 级文件;
- 进度文件必须及时刷盘:调用 .flush() 强制落盘,配合 os.fsync() 可进一步提升可靠性(尤其在 Linux/macOS 上);
- 考虑并发安全:若多进程/线程访问同一进度文件,需加锁(如 threading.Lock 或文件锁 portalocker);
- 备份原始文件:生产环境建议先对源文件做快照或校验(如 hashlib.md5),防止误操作;
- 替代方案补充:对极高可靠性要求场景,可选用 SQLite 存储每行处理状态(含时间戳、结果、错误信息),比纯文本进度文件更健壮。
该方法兼顾简洁性、可维护性与鲁棒性,是 Python 文件批处理工程实践中的通用范式。










