是否有一个快速的Java库来搜索字符串及其在文件中的位置?

时间:2012-02-08 17:09:36

标签: java string-search

我需要搜索大量文件(即600个文件,每个0.5 MB)以获取特定字符串。

我正在使用Java,所以我更喜欢将答案变成Java库,或者在最坏的情况下使用不同语言的库,我可以用Java调用它。

我需要搜索才能在文件中返回找到的字符串的确切位置(例如,Lucene似乎是不可能的。)

我需要尽可能快地进行搜索。

编辑START:

文件可能具有不同的格式(即EDI,XML,CSV),并且有时包含非常随机的数据(即数字ID等)。这就是为什么我初步排除了基于索引的搜索引擎的原因。

对于相似但不同的字符串,将多次搜索文件(即,对于可能具有相似长度和格式的ID,但它们通常会不同)。

编辑结束

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

每个0.5 MB的600个文件大约是300MB - 现在很难被认为是 big ,更不用说 large 了。在任何现代计算机上进行简单的字符串搜索实际上应该比CPU绑定更多的I / O限制 - 我的系统上的单个线程可以在1.5秒内搜索300MB以获得相对简单的正则表达式 - 如果文件的话,则下降到0.2已存在于OS缓存中。

考虑到这一点,如果你的目的是不经常进行这样的搜索,那么使用某种索引可能会导致过度设计的解决方案。首先迭代所有文件,逐行读取或逐行读取 - 这很简单,几乎不值得拥有自己的库。

设置性能要求,分析代码,验证实际的字符串搜索是瓶颈,然后 决定是否需要更复杂的解决方案。如果你确实需要更快的东西,你应该首先考虑以下解决方案,按照复杂程度:

  • 使用现有的索引引擎(例如Lucene)过滤掉每个查询的大部分文件,然后显式搜索(希望很少)其余文件中的字符串。

  • 如果您的文件不是真正的文本,那么基于字的索引可以工作,预处理文件以提取每个文件的术语列表并使用数据库创建自己的索引系统 - 我怀疑你会发现一个FTS引擎,它使用除了单词之外的任何东西进行索引。

  • 如果您确实希望将搜索时间缩短到最小,请从文件中提取术语/位置对,然后在数据库中输入那些。您可能仍需要通过查看实际文件进行验证,但速度要快得多。

PS:你根本没有提到 我们正在讨论的字符串之王。它是否包含分隔的术语,例如单词,或您的文件包含随机字符?搜索字符串可以以有意义的方式分解为子字符串,还是一堆字母?您的搜索字符串是固定的,还是也可以是正则表达式?每个问题的答案都可以显着限制实际可行的内容和实际可行内容 - 例如,索引随机字符串可能根本不可能。

修改

从问题更新来看,似乎术语/令牌的概念通常适用,而不是例如在二进制文件中搜索完全随机的序列。这意味着您可以索引这些条款。通过在索引中搜索搜索字符串中存在的任何标记,可以显着减少需要查看实际文件的情况。

  1. 您可以保留term->file索引。如果大多数术语对于每个文件都是唯一的,则此方法可能会提供良好的复杂性/性能折衷。基本上,您可以将搜索范围缩小到一个或两个文件,然后仅对这些文件执行完整搜索。

  2. 您可以保留term->file:position索引。例如,如果您的搜索字符串是“Alan Turing”。你首先会在索引中搜索令牌“Alan”和“Turing”。您将获得两个可以交叉引用的文件和位置列表。通过例如要求令牌“Alan”的位置在令牌“Turing”的位置之前最多,例如30个字符,您将获得文件中可以明确验证的候选位置列表。

  3. 我不确定现有索引库在多大程度上会有所帮助。大多数都是针对文本索引,可能会错误处理其他类型的令牌,例如数字或日期。另一方面,您的情况也没有根本不同,所以您可以使用它们 - 如果需要,可以通过预处理您提供的文件来使它们更加可口。根据您的需求构建自己的索引系统似乎也不太容易

    您仍未提及搜索字符串是否存在任何灵活性。你期望能够搜索正则表达式吗?搜索字符串是否应该逐字逐句地找到,或者您是否只需找到其中的条款?空白是否重要?这些条款的顺序是否重要?

    更重要的是,你没有提到你的文件中是否有任何结构在搜索时应该考虑。例如,您是否希望能够将搜索限制为XML文件的特定元素?

答案 1 :(得分:1)

除非您有SSD,否则您的主要瓶颈将是所有文件访问。无论你在Java中使用什么,它都需要大约10秒的时间来读取文件。

如果您有SSD,读取文件不会有问题,Java中的CPU速度会更重要。

如果您可以为文件创建索引,这将有很大帮助。