【问题标题】:C Sharp Folder Search by Using Regular Expression使用正则表达式的 C Sharp 文件夹搜索
【发布时间】:2011-03-10 14:40:08
【问题描述】:

从顶级目录中获取与某个正则表达式匹配的文件夹列表的最有效方法是什么?我目前只是递归地遍历子文件夹以查看它们是否与正则表达式匹配,如果匹配,我将使用目录路径获取文件名。

由于此目录中的文件夹数量众多,目前使用当前方法进行此搜索大约需要 50 分钟。

private void ProcessFiles(string path, string searchPattern)
{
    string pattern = @"^(\\\\server\\folder1\\subfolder\\(MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3}))))$";
    DirectoryInfo di = new DirectoryInfo(path);
    try
    {
        Debug.WriteLine("I'm in " + di.FullName);
        if (di.Exists)
        {
            DirectoryInfo[] dirs = di.GetDirectories("*", SearchOption.TopDirectoryOnly);
            foreach (DirectoryInfo d in dirs)
            {
                string[] splitPath = d.FullName.Split('\\');


                var dirMatch = new Regex(pattern, RegexOptions.IgnoreCase);

                if (dirMatch.IsMatch(d.FullName))
                {
                    Debug.WriteLine("---Processing Directory: " + d.FullName + " ---");
                    FileInfo[] files = d.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);
                    AddColor(files, splitPath);
                }
                ProcessFiles(d.FullName, searchPattern);
            }
        }


    }
    catch (Exception e)
    {

    }

}

【问题讨论】:

  • 50 分钟意味着你做错了什么。发布您的代码。
  • 或者:50 分钟意味着他有很多目录,或者包含的目录位于映射的 UNC 路径或其他慢速设备(如 U 盘、DVD 驱动器等)上。
  • @Abel:其中,我只会给 UNC 场景一个合理的机会。但无论如何,查看代码是“调试”它的合理第一步。
  • 这是一个巨大的目录列表,它包含了经过多年编译的大量图像文件。我可以索引该目录,我打算很快做,但我只是希望它尽可能高效地工作。
  • @Jesse:这里的效率意味着:在那个服务器上运行你的代码,而不是从远程位置。它将为您节省 99% 或更多的运行时间。

标签: c# regex search performance directory


【解决方案1】:

我会使用类似下面的东西,不需要递归,让 BCL 为你做这件事:

// I didn't recount the parenetheses...
Regex re = new Regex("MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3})))");
var dirs = from dir in 
           Directory.EnumerateDirectories(dirPath, "dv_*",
           SearchOption.AllDirectories)
           where re.IsMatch(dir)
           select dir;

如果它仍然运行 50 分钟,那么您只是在慢速驱动器、网络或类似设备上。

编辑:您编辑了您的问题。它清楚地表明您正在 UNC 路径上运行代码。这非常慢,如果您需要速度,请在该服务器本身上运行它。

注意:GetDirectories(您使用的)和EnumerateDirectories 的行为之间存在很大差异。微软文档says this about it

EnumerateDirectories 和 GetDirectories 方法的区别如下: 使用 EnumerateDirectories 时,可以在返回整个集合之前开始枚举名称集合;使用 GetDirectories 时,必须等待返回整个名称数组,然后才能访问该数组。因此,当您处理许多文件和目录时,EnumerateDirectories 会更高效。

关于你的问题:它会遍历它有权访问的所有目录,不要让它从你无权访问的目录开始(它会引发异常)。

【讨论】:

  • 您的方法如何处理我无权访问的目录?它会引发安全异常还是会跳过该目录?如果我无权访问特定的子目录,我不希望枚举中断。
  • 太棒了。我会试一试,看看会发生什么。
【解决方案2】:

为了在 imo 目录树上获得最快的结果,最好的方法是使用互操作。 FindFirstFile、FindNextFile、FindClose 是你的朋友。

http://msdn.microsoft.com/en-us/library/aa364418%28v=vs.85%29.aspx

但如果你有一棵大树要穿越,就不要指望光速了。

【讨论】:

    【解决方案3】:

    您可以在子文件夹上递归地启动其他线程,以尝试利用您系统的任何并行功能,但很可能大部分开销可能是磁盘访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多