使用pathlib对快速变化目录递归glob时出现FileNotFoundException如何处理
为什么会抛出异常而不是自动跳过
pathlib的rglob方法默认假设遍历期间目录结构是静态稳定的,没有内置动态目录变化场景的容错逻辑:它执行递归匹配时,会先拉取当前目录下的所有子条目列表,识别到子目录后就会尝试进入该目录继续递归,如果该目录刚好在「识别到存在」和「实际进入遍历」的间隙被删除,就会直接抛出FileNotFoundException。
标准库没有默认做自动跳过的处理,是为了避免静默吞掉非竞争场景下的真实目录访问错误,这种目录频繁增删的动态场景属于非常规使用场景,需要用户主动加容错逻辑。
精简规避方案
推荐两种可直接落地的方案,按精简程度排序:
方案1:迭代器异常捕获包装(最简,仅需6行代码)
写一个通用的迭代异常捕获包装器,直接包裹rglob的返回值即可,不需要修改原有遍历逻辑:
def safe_iter(glob_iter): iterator = iter(glob_iter) while True: try: yield next(iterator) except StopIteration: return except FileNotFoundError: # 跳过已被删除的目录,继续遍历剩余条目 continue
使用方式直接替换原有调用即可:
from pathlib import Path p = Path() # 原写法 list(p.rglob('*')) 替换为下面的写法 list(safe_iter(p.rglob('*')))
方案2:自定义递归遍历(可控性更高)
如果需要兼容更多异常场景(比如权限不足、软链接异常等),可以自己实现带异常捕获的递归遍历:
from pathlib import Path import os def safe_rglob(root: Path, pattern: str = "*"): # 先返回当前层级匹配的结果 yield from root.glob(pattern) # 遍历子目录,加异常捕获 for entry in os.scandir(root): if entry.is_dir(follow_symlinks=False): try: yield from safe_rglob(Path(entry.path), pattern) except (FileNotFoundError, PermissionError): # 遇到异常目录直接跳过 continue
内容的提问来源于stack exchange,提问作者nonForgivingJesus
相关产品推荐
相关产品推荐

