我要对4000个文件进行字符串搜索
本文关键字:字符串 搜索 文件 4000个 我要 | 更新日期: 2023-09-27 18:19:21
在多个文件中搜索字符串的最佳方法是什么?
目前我正在对每个文件进行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库。
很可能大部分时间都花在等待从磁盘读取文件上。在这种情况下,多线程并不能给您带来很大的帮助——现在有几个线程在等待磁盘IO,而不是一个线程在等待磁盘IO。
这个操作很大程度上是I/O限制的,所以并行处理不会给您带来任何额外的性能。您可以尝试使用第三方搜索库对文件进行索引,但就软件而言,这实际上是您所能做的一切。如果可以的话,将文件分割到多个驱动器并为每个驱动器使用不同的线程可以帮助加快速度。