处理大量文件

时间:2012-05-05 14:15:49

标签: c# file-io task-parallel-library async-ctp tpl-dataflow

我目前正在开展一项涉及索引大量文件(240k)的研究项目;它们主要是html,xml,doc,xls,zip,rar,pdf和文本大小从几KB到超过100 MB的文本。

提取了所有zip和rar文件后,我最终得到了一百万个文件。

我使用的是Visual Studio 2010,C#和.NET 4.0,支持TPL Dataflow和Async CTP V3。要从这些文件中提取文本,我使用Apache Tika(使用ikvm转换),并使用Lucene.net 2.9.4作为索引器。我想使用新的TPL数据流库和异步编程。

我有几个问题:

  1. 如果我使用TPL,我会获得性能优势吗?它主要是一个I / O流程,据我所知,当你大量使用I / O时,TPL并没有提供太多的好处。

  2. 生产者/消费者方法是否是处理此类文件处理的最佳方式,还是有更好的其他模型?我正在考虑使用blockingcollections创建一个具有多个使用者的生产者。

  3. TPL数据流库是否适用于此类流程?看来TPL Dataflow最适合用于某种消息传递系统......

  4. 在这种情况下,我应该使用异步编程还是坚持同步?

2 个答案:

答案 0 :(得分:1)

async / await 在处理外部资源时肯定有帮助 - 通常是Web请求,文件系统或数据库操作。这里有趣的问题是您需要同时满足多个要求

  • 消耗尽可能少的CPU(这是async / await将帮助的地方)
  • 同时执行多项操作,并行
  • 控制启动的任务数量(!) - 如果不考虑这一点,处理多个文件时可能会用完线程。

您可以查看我在github上发布的一个小项目:

Parallel tree walker

能够有效地在目录结构中枚举任意数量的文件。您可以定义异步操作以对每个文件执行(在您的情况下为其编制索引),同时仍然控制同时处理的最大文件数

例如:

await TreeWalker.WalkAsync(root, new TreeWalkerOptions
{
    MaxDegreeOfParallelism = 10,
    ProcessElementAsync = async (element) =>
    {
        var el = element as FileSystemElement;
        var path = el.Path;
        var isDirectory = el.IsDirectory;

        await DoStuffAsync(el);
    }
});

(如果你不能直接使用该工具作为dll,你仍然可以在源代码中找到一些有用的例子)

答案 1 :(得分:0)

您可以使用Everything Search。 SDK是开源的,有C#示例。 这是我在Windows上索引文件的最快方法。

来自常见问题解答

  

1.2索引文件需要多长时间?

     

“Everything”仅使用文件和文件夹名称,通常需要几秒钟来构建其>数据库。   全新安装的Windows XP SP2(大约20,000个文件)将需要大约1秒的时间来索引。   1,000,000个文件大约需要1分钟。

我不确定你是否可以使用TPL。