我的应用程序索引最终用户计算机上所有硬盘驱动器的内容。
我正在使用 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/