通过网络优化Dictionary.EnumerateFiles

Red*_*dow 6 .net c# optimization multithreading

我目前有一个扫描网络共享的程序.为此,它首先枚举共享上的所有文件和目录.这是一个非常缓慢的过程.我目前使用以下代码,取自本网站的2011年答案.

static class SafeWalk
    {
        public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOpt)
        {
            try
            {
                var dirFiles = Enumerable.Empty<string>();
                if (searchOpt == SearchOption.AllDirectories)
                {
                    dirFiles = Directory.EnumerateDirectories(path)
                                        .SelectMany(x => EnumerateFiles(x, searchPattern, searchOpt));
                }
                return dirFiles.Concat(Directory.EnumerateFiles(path, searchPattern));
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine(ex.Message);
                return Enumerable.Empty<string>();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是程序中的其他所有内容都是多线程的,并针对速度进行了优化.这是唯一一个严重阻碍我的领域.枚举网络共享中的文件可能需要几分钟.这是在Intranet上,我的机器和服务器之间有千兆位或更大的连接.

当我在运行时暂时将网络路径映射到驱动器时​​,我确实加快了速度.有什么办法可以让它变得更快吗?查看资源监视器,它几乎不使用任何CPU,内存或网络带宽.

abr*_*fra -2

快速目录枚举器 正适合您。

为什么它更快?

Directory.GetFiles 和 DirectoryInfo.GetFiles 或 Directory.EnumerateFile() 有许多缺点。最重要的是它们会丢弃信息并且无法有效地允许您同时检索有关多个文件的信息。

在内部,Directory.GetFiles 被实现为 Win32 FindFirstFile/FindNextFile 函数的包装器。这些函数都返回有关 GetFiles() 方法在返回文件名时丢弃的枚举的每个文件的信息。他们还使用单个网络消息检索有关多个文件的信息。

FastDirectoryEnumerator 保留此信息并将其返回到 FileData 类中。这大大减少了完成相同任务所需的网络往返次数。

  • 不,该项目早于在 .NET 4.0 中添加 EnumerateFiles/Directory() 方法。这解决了完全相同的问题。OP已经在使用它了。 (2认同)
  • 尝试使用这个库:在初始测试中,它比我当前的解决方案慢了大约 5 倍。 (2认同)