本文介绍如何在 python 中结合 pathlib 的 rglob 与已处理文件路径集合,高效过滤出待处理文件,避免重复 ocr 处理,解决内存溢出后断点续跑的核心需求。
本文介绍如何在 python 中结合 pathlib 的 rglob 与已处理文件路径集合,高效过滤出待处理文件,避免重复 ocr 处理,解决内存溢出后断点续跑的核心需求。
在处理海量扫描文档(如 20 万文件)时,因 OOM 中断后需跳过已成功 OCR 的文件——关键在于基于文件逻辑标识(而非扩展名)精准排除。你提供的已处理路径列表(如 /home/user/output/Google/OCR/.../processed-xxx 或 /.../Screenshot_20220826-142620_Office)均位于 outputpath 下,且不含扩展名;而待扫描的原始文件位于 companypath,扩展名多样(.jpg, .pdf, .tiff 等)。因此,排除逻辑应聚焦于路径基名(stem)匹配:提取已处理路径的 stem,再比对待处理文件的 stem 是否已在该集合中。
以下是优化后的完整实现方案:
import sys
from pathlib import Path
import itertools
companyfolder = sys.argv[1]
companypath = Path("/home/user/download/") / companyfolder
outputpath = Path("/home/user/output/") / companyfolder / "OCR"
errorpath = Path("/home/user/output/") / companyfolder
# 步骤 1:构建已处理文件 stem 集合(O(1) 查找,推荐用 set)
processed_stems = set()
# 假设你已将已处理路径保存为文本文件 processed_list.txt,每行一个路径
with open("processed_list.txt", "r") as f:
for line in f:
line = line.strip()
if line:
p = Path(line)
processed_stems.add(p.stem) # 只取文件名(不含扩展名和路径)
# 步骤 2:定义所有支持的原始文件扩展名(统一小写便于匹配)
extensions = {".jpeg", ".jpg", ".png", ".tif", ".tiff", ".bmp", ".pdf"}
# 步骤 3:生成待处理文件迭代器,并实时过滤
for file in itertools.chain.from_iterable(
companypath.rglob(f"*{ext}") for ext in extensions
):
# 关键:用 stem 匹配,忽略大小写和扩展名差异
if file.stem in processed_stems:
continue # 跳过已处理文件
try:
print(f"Processing: {file}")
# ✅ 此处插入你的 OCR 处理逻辑
# 例如:result = ocr_engine.process(file)
# save_result(result, outputpath / f"{file.stem}.txt")
# (可选)处理成功后,可将当前 stem 加入 processed_stems(若需动态更新)
# processed_stems.add(file.stem)
except Exception as e:
print(f"Error processing {file}: {e}")
# 记录错误到 errorpath,便于后续重试
(errorpath / "errors.log").open("a").write(f"{file} -> {e}\n")✅ 关键设计说明:
- 使用 set 存储 stem(而非完整路径),内存占用低、查询快,完美适配 25k+ 条目;
- rglob 按扩展名分组调用,避免重复遍历目录树,比 **/* 通配更可控;
- itertools.chain.from_iterable 替代长链 chain(...),代码更简洁、可维护;
- 所有路径操作使用 Path 对象,跨平台安全,自动处理斜杠。
⚠️ 注意事项:
- 确保 processed_list.txt 中的路径与 outputpath 结构一致(你示例中路径已含完整 OCR/...,故 stem 提取准确);
- 若原始文件名含特殊字符(如空格、方括号),Path.stem 仍能正确解析,无需额外清洗;
- 生产环境建议添加日志模块(logging)替代 print,并启用 concurrent.futures 并行加速 OCR;
- 首次运行前,可先用 len(list(...)) 验证待处理文件数是否符合预期(如 200k - 25k ≈ 175k)。
通过此方案,脚本将严格跳过所有 stem 已存在于记录中的文件,实现可靠、高效的断点续处理,彻底规避 OOM 后的重复劳动。

















