列出所有与定义的路径模式匹配的文件夹

3

我需要对文件共享中与定义的模式匹配的所有文件夹执行一些操作。该模式可能涉及树中的多个级别,例如 \Test\[a-z]+\Project[0-9]{3}

遍历树以查找所有匹配文件夹的最有效方法是什么?是否有比使用DirectoryInfo和di.GetDirectories()进行简单递归深度优先搜索更好的方法,如下所示:

private void TraverseSubFolder(DirectoryInfo folder)
{
    if (filter.IsMatch(folder.FullName)) {
       DoStuff(folder);
    }

    DirectoryInfo[] subFolders = folder.GetDirectories();
    foreach (DirectoryInfo sf in subFolders)
    {
        TraverseSubFolder(sf);
    }
}
2个回答

4
您可以使用Linq进行筛选。
Regex regex = new Regex("your regex");
var directories = Directory.GetDirectories("c:\\", null, SearchOption.AllDirectories).Where(directory => regex.IsMatch(directory));

这种方法的缺点是它仍然会搜索被过滤掉的不想要的文件夹,因为Where出现在所有文件夹返回之后。这可以进行改进。 编辑 由于一旦您遇到没有权限的文件夹,就会抛出UnauthorizedAccessException异常,因此这将无法使用SearchOption.AllDirectories。
我认为您不能避免使用递归函数,因为需要检查UnauthorizedAccessException。
我使用Linq编写了这个方法,但与您自己的方法并没有太大区别。至少它检查了权限。它仍然容易出现StackOverflowException。
private static void Traverse(List<string> folders, string rootFolder, Regex filter)
{
    try
    {
        // Test for UnauthorizedAccessException
        new FileIOPermission(FileIOPermissionAccess.PathDiscovery, rootFolder).Demand();

        Array.ForEach(Directory.GetDirectories(rootFolder),
            (directory) =>
            {
                if (filter.IsMatch(directory))
                {
                    folders.Add(directory);

                    Traverse(folders, directory, filter);
                }
            });
    }
    catch 
    {
        // Ignore folder that we don't have access to
    }
}

// Usage example
List<string> folders = new List<string>();
Regex regex = new Regex("^.+$");
Traverse(folders, "e:\\projects", regex);

这实际上比我的递归搜索要慢一些(尽管它肯定更优雅)。有没有办法处理未经授权的访问异常? - Dexter
是的,它会变慢,因为它会遍历不应该去的地方,因为过滤器发生在整个遍历之后。至于访问异常,我以为GetDirectories正在处理它。奇怪。我想你可以用Reflector检查GetDirectories。 - Pierre-Alain Vigeant
感谢您的编辑 - 这是非常方便的信息。我对大约5500个文件夹的树进行了一些快速测试(由于未经授权的访问异常,无法尝试更多),我的递归DirectoryInfo调用时间为2.10秒,您原始的带有LINQ过滤器的GetDirectories过程为3.50秒,@Nestor的方法为4.47秒,随后是正则表达式模式匹配。我的递归方法仍然进入不匹配的文件夹,因为子文件夹可能匹配,即使它们的父文件夹不匹配,所以这对我来说并不能解释时间差异。 - Dexter

0

Directory.GetDirectories(..,.., SearchOption.AllDirectories)

Directory.GetDirectories(..,.., SearchOption.AllDirectories)

是一个用于在指定路径中搜索子目录的方法。其中,第一个参数表示要搜索的目录路径,第二个参数表示要搜索的目录名称的匹配模式,第三个参数表示搜索选项,可以选择只搜索当前目录或者搜索所有子目录。


那行不通,他试图在完整路径上进行模式匹配。 - Russell Steen
搜索模式参数是否支持具有多级文件夹的模式(例如我问题中的模式)?它似乎不支持正则表达式模式,例如,我在网络上找不到除 . 等之外的好示例。 - Dexter
返回的文件将是完整路径。因此,您可以在它们上应用正则表达式。 - Nestor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接