2

我需要获取所有 Word 文档的列表。*.doc 和 *.docx 存储在基于 Windows 的文件夹中,包含许多子文件夹和子子文件夹等...

用 C# 搜索文件有一个可行的答案,它有 2 年历史,搜索 1500 个文件需要 10 秒,(将来可能有 10,000 个或更多)。我将发布我的代码,该代码基本上是上述链接的副本。有没有人有更好的解决方案?

DateTime dt = DateTime.Now;
DirectoryInfo dir = new DirectoryInfo(MainFolder);
List<FileInfo> matches = 
          new List<FileInfo>(dir.GetFiles("*.doc*",SearchOption.AllDirectories));
TimeSpan ts = DateTime.Now-dt;
MessageBox.Show(matches.Count + " matches in " + ts.TotalSeconds + " seconds");
4

4 回答 4

5

您可以使用Directory.EnumerateFiles而不是GetFiles. 这样做的好处是将文件作为 . 返回IEnumerable<T>,这使您可以立即开始处理结果集(而不是等待返回整个列表)。

如果您只是计算文件数量或列出所有文件,它可能无济于事。但是,如果您可以对结果进行处理和/或过滤,特别是如果您可以在其他线程中执行任何操作,则速度会明显加快。

从文档中:

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

于 2012-05-15T16:25:11.790 回答
2

怀疑你可以做很多事情,

dir.GetFiles("*.doc|*.docx", SearchOptions.AllDirectories)可能会产生影响,因为它是更具限制性的模式。

于 2012-05-15T16:29:27.043 回答
1

第一次我建议您使用 StopWatch 而不是 DateTime 来获取经过的时间。
第二次为了使您的搜索更快,您不应该将 GetFiles 的结果存储在 List 中,而是直接存储到数组中。
最后,您应该优化您的搜索模式:您想要每个 doc 和 docx 文件,尝试“*.doc?”
这是我的建议:

var sw = new Stopwatch();
sw.Start();

var matches = Directory.GetFiles(MainFolder, "*.doc?", SearchOption.AllDirectories);

sw.Stop();
MessageBox.Show(matches.Length + " matches in " + sw.Elapsed.TotalSeconds + " seconds");
于 2012-05-15T16:35:55.260 回答
1

如果您想要完整列表,除了确保在目标文件夹上启用了 Windows 索引服务之外,不是真的。您的主要延迟将从硬盘驱动器读取,并且没有优化您的 C# 代码将使该过程更快。您可以创建自己的简单索引服务,也许使用FileSystemWatcher,无论添加多少文档,它都会为您提供亚秒级的响应时间。

于 2012-05-15T16:27:34.890 回答