在多个文件中搜索字符串的最佳方法是什么?
目前,我正在对每个文件进行 foreach 循环,但注意到浏览所有 4000 多个文件最多需要 4-5 分钟
是否有某种并行的方式来做到这一点?
在多个文件中搜索字符串的最佳方法是什么?
目前,我正在对每个文件进行 foreach 循环,但注意到浏览所有 4000 多个文件最多需要 4-5 分钟
是否有某种并行的方式来做到这一点?
最好的方法是生产者消费者模型。你这样做是你有一个线程从硬盘驱动器读取并将数据加载到队列中,然后你有不确定数量的其他线程处理数据。
所以说你的旧代码是这样的
foreach(var file in Directory.GetFiles(someSearch)
{
string textToRead = File.ReadAllText(file);
ProcessText(textToRead)
}
新代码将是
var collection = new BlockingCollection<string>(); //You may want to set a max size so you don't use up all your memory
Task producer = Task.Run(() =>
{
foreach(var file in Directory.GetFiles(someSearch)
{
collection.Add(File.ReadAllText(file))
}
collection.CompleteAdding();
});
Parallel.ForEach(collection.GetConsumingEnumerable(), ProcessText); //Make sure any actions ProcessText does (like incrementing any variables in the class) is done in a thread safe manner.
它的作用是让一个线程从硬盘驱动器读取数据,而不是与任何其他线程争夺 I/O,但它允许多个线程同时处理所有读取的数据。
如果您定期进行此搜索,请考虑使用某些搜索引擎(如 Solr)为您的文件编制索引。文件被索引后,搜索将花费几毫秒。
您还可以在您的应用程序中嵌入搜索引擎,例如,使用 Lucene 库。
此操作主要受 I/O 限制,因此并行处理不会真正为您提供任何额外的性能。您可以尝试使用 3rd-party 搜索库对文件进行索引,但就软件而言,这实际上是您所能做的。如果可以的话,将文件拆分到多个驱动器并为每个驱动器使用不同的线程可以帮助加快速度。
很可能大部分时间都花在等待从磁盘读取文件上。在这种情况下,多线程不会对您有很大帮助 - 不是让一个线程等待磁盘 IO,而是现在有多个线程在等待磁盘 IO。