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

C#中Directory.GetFiles使用AllDirectories搜索不生效问题咨询

问题说明

开发了一款用于识别、复制选定文件的程序,传入固定已知路径时运行正常。新增通配符检索功能:给定文件存储顶层目录,自动匹配符合文件名规则的目标文件,初始实现代码如下:

string Fol = "C:\testpath\test";  
string[] testfol = Directory.GetFiles(Fol, "filename-*", SearchOption.TopDirectoryOnly);  
if (Directory.Exists(Fol))  
    foreach (var file in testfol)  
    {  
        defaultPaths.Add($@"{file}");  
    }

代码中defaultPaths.Add的作用是将匹配到的文件加入固定采集的标准项列表。
故障现象:将搜索参数替换为SearchOption.AllDirectories后,程序既不搜索子目录,也不检索Fol对应的根目录,直接跳过整个文件复制流程。需要明确两个SearchOption枚举值的运行逻辑差异,定位故障原因。

核心逻辑差异与故障原因

两个枚举值的运行逻辑存在本质区别:

  • SearchOption.TopDirectoryOnly:仅遍历传入的顶层目录,匹配符合通配符规则的文件后直接返回结果,全程不会进入任何子目录,不会触发子目录相关的权限校验、访问异常,容错阈值高。
  • SearchOption.AllDirectories:递归遍历顶层目录下的所有层级子目录,遍历过程中只要任意一个节点出现异常,整个方法会直接终止并抛出异常,不会返回任何已匹配到的结果。

结合代码实现,故障通常由三个问题触发:

  1. 执行顺序错误:代码先调用Directory.GetFiles执行检索,再通过Directory.Exists(Fol)判断目录是否存在。如果路径本身不合法,TopDirectoryOnly模式下可能直接返回空数组不抛错,但AllDirectories模式会直接抛出路径不存在的异常,若外层做了吞错处理,就会表现为整个流程直接跳过。
  2. 子目录访问异常:这是最常见的诱因。如果目标路径下存在受系统保护的目录、需要管理员权限才能访问的目录、被占用锁定的目录,递归遍历到该目录时会抛出UnauthorizedAccessException或IOException,导致整个检索直接失败,连根目录下匹配到的文件都无法返回。
  3. 路径转义错误:代码中定义路径的字符串"C:\testpath\test"未加逐字前缀@,字符串内的\t会被编译器解析为制表符,实际传入的路径是非法值。TopDirectoryOnly模式下部分环境的路径容错机制可能不会触发报错,但AllDirectories递归校验路径时会直接抛出异常。
修复方案
  • 调整代码执行顺序:先校验目录是否存在,再执行文件检索操作
  • 替换原生Directory.GetFiles的全目录遍历逻辑,改用手动递归实现,单个子目录访问失败时直接跳过,不中断整体检索流程
  • 所有Windows路径字符串统一添加逐字前缀@,避免转义字符导致的路径错误

修正后的可运行参考代码:

// 路径添加@前缀,避免转义错误
string Fol = @"C:\testpath\test";
if (Directory.Exists(Fol))
{
    foreach (var file in GetFilesRecursive(Fol, "filename-*"))
    {
        defaultPaths.Add(file);
    }
}

// 自定义递归检索方法,自动跳过无权限/不存在的目录
IEnumerable<string> GetFilesRecursive(string rootPath, string searchPattern)
{
    // 先返回当前目录下匹配的文件
    foreach (var file in Directory.EnumerateFiles(rootPath, searchPattern, SearchOption.TopDirectoryOnly))
    {
        yield return file;
    }
    // 遍历所有子目录
    foreach (var dir in Directory.EnumerateDirectories(rootPath))
    {
        IEnumerable<string> subFiles;
        try
        {
            subFiles = GetFilesRecursive(dir, searchPattern);
        }
        catch (UnauthorizedAccessException)
        {
            // 无权限访问的目录直接跳过
            continue;
        }
        catch (DirectoryNotFoundException)
        {
            // 遍历过程中被删除/移动的目录直接跳过
            continue;
        }
        foreach (var file in subFiles)
        {
            yield return file;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 18:27:39