You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Python目录递归遍历中的‘Too many open files’错误?

问题分析与修复方案

原代码的核心问题

  • 无限递归调用:函数里每次递归都传入rootdir,相当于反复扫描同一个根目录,无限调用自身,疯狂创建文件句柄,直接耗尽系统的文件描述符配额,触发Too many open files错误,最终导致栈溢出出现段错误。
  • 逻辑顺序错误:sys.exit("Directory is empty")之后的if dir.is_dir()永远不会执行,而且空目录的判断放在循环遍历每个条目的时候,完全不符合逻辑——应该是进入目录后先检查是否为空,而不是遍历每个条目都检查一次。
  • 冗余操作:循环内重复调用os.listdir(rootdir),完全没必要,浪费系统资源。

修复后的递归实现

先修正递归逻辑,确保只遍历每个子目录一次:

import os
import sys

rootdir = 'build/system/'

def list_dirs(current_dir):
    # 先尝试获取目录条目
    try:
        entries = os.scandir(current_dir)
    except OSError as e:
        print(f"无法访问目录 {current_dir}: {e}")
        return
    
    has_entries = False
    for entry in entries:
        has_entries = True
        if entry.is_dir(follow_symlinks=False):  # 可选:跳过符号链接避免循环
            # 在这里执行你需要的操作,比如打印目录路径
            print(f"处理目录: {entry.path}")
            # 递归遍历子目录,传入当前子目录的路径
            list_dirs(entry.path)
    
    # 显式关闭迭代器(Python 3.6+会自动处理,显式操作更稳妥)
    entries.close()
    
    if not has_entries:
        print(f"空目录: {current_dir}")
        # 若遇到空目录需要终止程序,取消下面注释
        # sys.exit("Directory is empty")

# 启动遍历
list_dirs(rootdir)

更优的非递归实现(推荐)

如果子目录层级极深,递归可能触发RecursionError(栈溢出),推荐用Python内置的os.walk,它是迭代式实现,更高效且避免递归栈问题:

import os
import sys

rootdir = 'build/system/'

for dirpath, dirnames, filenames in os.walk(rootdir):
    # dirpath是当前目录路径,dirnames是当前目录下的子目录列表
    print(f"处理目录: {dirpath}")
    
    # 如果需要处理空目录
    if not dirnames and not filenames:
        print(f"空目录: {dirpath}")
        # 若遇到空目录要终止程序,取消下面注释
        # sys.exit("Directory is empty")

为什么能解决问题

  • 修复后的递归代码:每次递归传入当前子目录的路径,不会重复扫描根目录,避免了无限递归,同时合理处理了空目录判断和资源释放。
  • os.walk:Python内部用迭代方式遍历目录树,不需要手动管理递归栈,也不会因为层级过深导致栈溢出,而且底层实现高效,能避免文件句柄泄漏问题。

内容的提问来源于stack exchange,提问作者LM10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:40:39