2013-02-12 185 views
13

我需要使用C#在一组文本文件中搜索大约13个字符的字符串。文本文件的数量正在变化,范围可能在100-1000之间。文件的大小可以在1KB到10MB之间。在文本文件中搜索字符串的更快方法

我试着打开每个文件的幼稚方式,逐行读取它并查看该字符串是否存在(使用index.of),但这太慢了。我也尝试过使用Boyer-Moore算法,该算法的确提高了5秒钟的时间,但仍然感觉很慢。

关于如何加快搜索的任何想法?

+2

您的放缓可能来自逐行读取文件。一次将所有文件读入内存并进行搜索。 – dda 2013-02-12 07:17:20

+0

http://stackoverflow.com/questions/4289353/fastest-way-to-search-ascii-files-in-c-sharp-for-simple-keywords – Ofiris 2013-02-12 07:22:55

+0

您是否需要多次对相同的文件执行搜索? – user626528 2013-02-12 07:48:02

回答

3

你应该考虑使用带有内容的操作系统文件搜索。看看Microsoft Windows Search 3.x SDK

或者你可以利用PLINQ搜索文件数组。请参阅此链接:

File Content and Directory Search using Directory.GetFiles and PLINQ

+1

不是downvoting,但我可以理解它:你只是做一个愚蠢的解决方案(基本上IndexOf)与PLINQ并行,这并不是一个好的解决方案 - 你基本上只是抛出更多的硬件,从而使它更快。这就像告诉这个人在多个线程中阅读和处理他的文件。他建议使用博尔摩尔比这要好得多。此外,我不确定MS Search是否支持自定义标记,这似乎是一项要求。所以,在我看来,作为一名搜索专家,这里的答案比你的要好得多。对不起......我很欣赏好意。 – atlaste 2013-02-12 08:11:41

+0

太棒了! PLINQ是最疯狂的!只是几行!我用ReadAllText代替,这是最快的。 – 2018-02-06 03:06:51

3

两个选项浮现在脑海中:

读取内存中的文本文件中,只是搜索整个字符串一次。

如果这证明太慢或太饿,请使用像Apache Lucene这样的索引器。有一个很好的和简单的SDK为可用于.NET,称为Lucene.net

这里是它的一个小介绍: http://www.codeproject.com/Articles/29755/Introducing-Lucene-Net

1

如果您的计算机可以处理它尝试加载的所有文本文件到内存(使用technique shown here,然后评估内存中的文本

如果你不能一次处理所有的文件,那么对于最小的文件做这个,文件I/O将成为你最大的花费,所以你想尽可能地减少它。

8

根据ho很多时候你想要做'搜索',你想要使用搜索引擎。如果你想搜索很多次,使用搜索引擎,否则:不要。我将要描述如何在这里实现这两个场景。

当使用搜索引擎时:这听起来像是在寻找子串,这意味着您应该使用您最喜爱的搜索引擎(最好是您可以自定义的文件(lucene,terrier等))为您的文件编制索引。您需要的技术是索引三元组,即:所有三个字符的组合都必须进行索引。 F.ex .:'foobar'会产生'foo','oob','oba'和'bar'。在搜索时,您希望对查询执行相同操作,并使用所有这些卦的AND来发出搜索引擎查询。 (这将在文档的发布列表上运行合并连接,这将返回其ID或发布列表中的任何内容)。

或者,您可以实现后缀数组并索引文件一次。如果你想搜索短的(1-2个字符)子串,这将给予更多的灵活性,但是在索引方面更难以维护。 (在CWI /阿姆斯特丹有一些关于快速索引后缀数组的研究)

当您只想搜索几次时,要使用的算法是Boyer-Moore(我通常使用Boyer-moore-sunday [Graham A. Stephen,字符串搜索])或编译的DFA(您可以从NFA构建它们,这更容易制作)。但是,这只会给你一个小的速度提升,原因很简单,磁盘IO可能是你的瓶颈,比较你需要解码的一堆字节非常快。

你可以做的最大的改进不是逐行读取文件,而是逐块读取。如果可以,应该配置NTFS使用64 KB的块大小,并且以64 KB的倍数读取这些文件 - 在单次读取中认为4 MB或更多。我甚至建议使用异步IO,以便可以同时读取和处理(先前读取的数据)。如果你正确地做到了这一点,它应该已经在大多数现代硬件上为你提供了10 MB的实施。

最后但并非最不重要的一点,在整个信息检索过程中使用的整洁技巧也是使用快速压缩算法压缩数据。由于磁盘IO比内存/ CPU操作慢,这可能也会有帮助。 Google的Snappy压缩器是快速压缩算法的一个很好的例子。

1

您可以使用Microsoft的索引服务搜索要添加到目录中的文件夹中的文档。 Here是一篇非常不错的文章,可供用户搜索文本文件