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

2023-09-03 21:09:44 作者:许你三千笔墨画我绝世倾城

我需要在内部文件共享相匹配定义的模式中所有文件夹执行某些操作。该图案可以指多个层次树中的,例如 \测试\ [A-Z] + \项目[0-9] {3}

什么是遍历树找到所有匹配的文件夹的最有效方法是什么?有没有更好的方法比使用DirectoryInfo的和di.GetDirectories(),一个简单的递归深度优先搜索做到这一点像这样的:

 私人无效TraverseSubFolder(DirectoryInfo的文件夹)
{
    如果(filter.IsMatch(folder.FullName)){
       DoStuff(文件夹);
    }

    DirectoryInfo的[]子文件夹= folder.GetDirectories();
    的foreach(DirectoryInfo的SF中的子文件夹)
    {
        TraverseSubFolder(SF);
    }
}
 

解决方案

您可以使用LINQ筛选

 正则表达式的regex ​​=新的正则表达式(你的正则表达式);
var目录= Directory.GetDirectories(C:\\,空,SearchOption.AllDirectories)。凡(目录=> regex.IsMatch(目录));
 
常用设计模式的定义及结构图

这种方法的缺点是,它仍然会搜索到,因为被过滤掉不需要的文件夹中的其中,返回的所有文件夹后,会出现。

这可能会进行调整。

修改

这不会SearchOption.AllDirectories只要你打,你没有权利的文件夹,因为工作,UnauthorizedAccessException将被抛出。

我不认为你可以去,因为检查UnauthorizedAccessException没有一个递归函数。

I codeD使用LINQ这种方法,但它不是从你自己的方法非常不同。至少它检查的权限。它仍然是容易发生StackOverflowException

 私有静态无效导线(名单<字符串>文件夹,串rootFolder,正则表达式过滤器)
{
    尝试
    {
        //测试UnauthorizedAccessException
        新的FileIOPermission(FileIOPermissionAccess.PathDiscovery,rootFolder).Demand();

        Array.ForEach(Directory.GetDirectories(rootFolder)
            (目录)=>
            {
                如果(filter.IsMatch(目录))
                {
                    夹Folders.Add(目录);

                    特拉弗斯(文件夹,目录,过滤器);
                }
            });
    }
    抓住
    {
        //忽略的文件夹,我们没有获得
    }
}

//使用示例
名单<字符串>文件夹=新的名单,其中,串>();
正则表达式的regex ​​=新的正则表达式(^ + $);
特拉弗斯(文件夹中,E:\\项目,正则表达式);
 

I need to perform some operations on all folders within a file share which match a defined pattern. The pattern may refer to a number of levels in the tree, e.g. \Test\[a-z]+\Project[0-9]{3}

What is the most efficient way to traverse the tree to find all matching folders? Is there a better way to do this than a simple recursive depth first search using DirectoryInfo and di.GetDirectories(), like such:

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

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

解决方案

You could use Linq to filter

Regex regex = new Regex("your regex");
var directories = Directory.GetDirectories("c:\\", null, SearchOption.AllDirectories).Where(directory => regex.IsMatch(directory));

The drawback of this approach is that it will still search into unwanted folder that were filtered out since the Where occurs after all folders are returned.

This could be adapted.

Edit

This will not work with SearchOption.AllDirectories since as soon as you hit a folder where you have no right, UnauthorizedAccessException will be thrown.

I don't think you can go without a recursive function because of the check for UnauthorizedAccessException.

I coded this approach using Linq, but it is not very different from your own approach. At least it check for permission. It is still prone to a 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);