在300万个文本文件中搜索匹配项

时间:2013-11-13 09:49:51

标签: java file-io

我有一个简单的要求,即用户输入一堆单词,系统会扫描超过300万个文本文件,并找到包含这些关键字的文件。没有复杂的搜索/索引算法,实现这一目标的最有效和最简单的方法是什么?

我想过使用Scanner类,但不知道这些大文件的性能。性能不是很高的优先级,但它应该是一个可接受的标准。

5 个答案:

答案 0 :(得分:6)

  

它应该是一个可接受的标准

我们不知道可接受的标准是什么。如果我们谈论交互式用户,可能就不会有一个简单的解决方案来扫描300万个文件并返回一些内容,比如说< 5秒。

合理的解决方案是搜索索引,可能基于Lucence

扫描仪/ grep / find等基于解决方案的主要问题是它们很慢,无法扩展,并且必须反复进行昂贵的扫描工作(除非您存储中间结果......但这并不简单,基本上是一个劳动力昂贵的重新实现索引器)。使用索引时,索引的创建和更新都很昂贵,查询很便宜。

答案 1 :(得分:0)

  

如果没有复杂的搜索/索引算法,实现这一目标的最有效和最简单的方法是什么?

复杂的搜索/索引算法。这里没有必要重新发明轮子。由于用户可以输入任何单词,因此无法进行简单的预处理步骤,而是必须为文本中的所有单词编制索引。这就像Lucene为你做的事情。

除了通过预处理和构建索引之外,没有其他快速搜索文本的方法。您可以为此推出自己的解决方案,也可以使用Lucene。

没有预处理的朴素文本搜索将太慢而无法使用。

答案 2 :(得分:0)

为什么不将系统调用包装到grep?您可以通过Runtime类实现此目的。

答案 3 :(得分:0)

解析每个文本文件时,我会使用BufferedReader并检查每行文本是否匹配。

BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
   // Does this line containe the text?
   if(line.contains(text)) {
      System.out.println("Text found");
   }
}
br.close();

我不确定这对于如此大量的文件是否会非常快。

答案 4 :(得分:0)

What would be the most efficient and simple way to implement this without a complex searching / indexing algorithm

如果您不使用任何类型的索引算法,则每次提交搜索时,都需要读取每个文件。这样做的开销不在于“匹配”算法,而在于I / O延迟。所以,我不太关心用什么来匹配; Scanner是直截了当的选择。

如果要提高性能,则需要使用某种预处理。您可以在内存中加载文件,大小允许。您可以为每个文件(索引)创建一组单词。您可以搜索太多算法,尤其是Map / Reduce上下文中的“字数”示例。如果要实现更高的并发性,您可能还需要了解Java的Fork/Join框架。