在多个文件中搜索多个字符串

Ich*_*ann 6 c# string search file visual-studio-2010

我有一个包含21000个字符串(每行一行)和500 MB其他文本文件(maily源代码)的文本文件.对于每个字符串,我需要确定它是否包含在任何这些文件中.我编写的程序可以完成这项工作,但是它的性能非常糟糕(它会在几天内完成,我需要在最多5-6小时内完成工作).
我正在使用C#,Visual Studio 2010编写

关于我的问题,我有几个问题:
a)哪种方法更好?

foreach(string s in StringsToSearch)
{
    //scan all files and break when string is found
}
Run Code Online (Sandbox Code Playgroud)

要么

foreach(string f in Files)
{
    //search that file for each string that is not already found
}
Run Code Online (Sandbox Code Playgroud)

b)逐行扫描一个文件是否更好

StreamReader r = new StreamReader(file);
while(!r.EndOfStream)
{
    string s = r.ReadLine();
    //... if(s.Contains(xxx));
}
Run Code Online (Sandbox Code Playgroud)

要么

StreamReader r = new StreamReader(file);
string s = r.ReadToEnd();
//if(s.Contains(xxx));
Run Code Online (Sandbox Code Playgroud)

c)线程是否会改善性能以及如何做到这一点?
d)是否有任何软件可以做到这一点,所以我不必编写自己的代码?

Cam*_*ner 6

如果您只是想知道是否找到字符串,并且不需要进行任何进一步处理,那么我建议您只使用grep.Grep非常快,专为这类问题而设计.

grep -f strings-file other-files...
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩.我确定那里有一个Windows实现.在最坏的情况下,Cygwin会拥有它.

编辑:这回答问题d)


Hen*_*man 4

您希望最大限度地减少文件 I/O,因此您的第一个想法非常糟糕,因为您将打开“其他”文件多达 21.000 次。您想使用基于第二个(a1)的东西。当其他文件不是太大时,使用 readAllText 将它们加载到内存中。

List<string> keys = ...;    // load all strings

foreach(string f in Files)
{
    //search for each string that is not already found
    string text = System.IO.File.ReadAllText(f);  //easy version of ReadToEnd


    // brute force
    foreach(string key in keyes)
    {
        if (text.IndexOf(key) >= 0) ....
    }

}
Run Code Online (Sandbox Code Playgroud)

蛮力部分可以改进,但我认为你会发现它是可以接受的。