我的应用程序索引最终用户计算机上所有硬盘驱动器的内容。
我正在使用 Directory.GetFiles 和 Directory.GetDirectories 递归处理整个文件夹结构。我只索引了几个选定的文件类型(最多 10 个文件类型)。

我在探查器中看到,大部分索引时间都花在枚举文件和文件夹上——这取决于实际索引最多 90% 的时间的文件比例。

我想让索引尽可能快。我已经优化了索引本身和索引文件的处理。

我正在考虑使用 Win32 API 调用,但我实际上在分析器中看到大部分处理时间实际上都花在了这些由 .NET 完成的 API 调用上。

是否有可以从 C# 访问的(可能是低级的)方法可以使文件/文件夹的枚举至少部分更快?

按照评论中的要求,我当前的代码(只是一个修剪了不相关部分的方案):

    private IEnumerable<IndexedEntity> RecurseFolder(string indexedFolder)
    {
        //for a single extension:
        string[] files = Directory.GetFiles(indexedFolder, extensionFilter);
        foreach (string file in files)
        {
            yield return ProcessFile(file);
        }
        foreach (string directory in Directory.GetDirectories(indexedFolder))
        {
            //recursively process all subdirectories
            foreach (var ie in RecurseFolder(directory))
            {
                yield return ie;
            }
        }
    }

最佳答案

在 .NET 4.0 中,有内置的 enumerable file listing methods ;因为这不远,我会尝试使用它。如果您有任何大量填充的文件夹(需要大量阵列分配),这可能是一个特别的因素。

如果深度是问题,我会考虑扁平化您的方法以使用本地堆栈/队列和单个迭代器块。这将减少用于枚举深层文件夹的代码路径:

    private static IEnumerable<string> WalkFiles(string path, string filter)
    {
        var pending = new Queue<string>();
        pending.Enqueue(path);
        string[] tmp;
        while (pending.Count > 0)
        {
            path = pending.Dequeue();
            tmp = Directory.GetFiles(path, filter);
            for(int i = 0 ; i < tmp.Length ; i++) {
                yield return tmp[i];
            }
            tmp = Directory.GetDirectories(path);
            for (int i = 0; i < tmp.Length; i++) {
                pending.Enqueue(tmp[i]);
            }
        }
    }

迭代它,从结果中创建您的 ProcessFile

关于c# - 递归处理文件夹中文件的快速(低级)方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2085452/

10-12 07:29
查看更多