Java:如何在LARGE二进制文件中查找字符串模式?

时间:2014-04-28 20:19:49

标签: java algorithm pattern-matching out-of-memory binaryfiles

我正在尝试编写一个程序,它将读取非常大的二进制文件并尝试查找2个不同字符串的出现,然后打印与模式匹配的索引。为了示例,我们假设字符序列是[H,e,l,l,o][H,e,l,l,o, ,W,o,r,l,d]

我能够为小二进制文件编写代码,因为我将每个字符作为一个字节读取,然后将其保存在Arraylist中。然后从Arraylist的开头开始,我将byte arraylist(byte[] data)byte[] pattern进行比较。

我需要找到一种方法来做同样的事情,但不要将整个二进制文件写入内存中进行比较。这意味着我应该能够在阅读每个字符时进行比较(我不应该将整个二进制文件保存在内存中)。假设二进制文件只包含字符。

有关如何实现这一目标的任何建议?提前谢谢大家。

4 个答案:

答案 0 :(得分:5)

好像你真的在寻找Aho-Corasick string matching algorithm

该算法根据您拥有的给定字典构建自动机,然后允许您使用输入字符串的单次扫描查找匹配项。

维基百科文章链接到this java implementation

答案 1 :(得分:2)

谷歌“有限状态机”。

或者,一次读取一个字节的文件,如果该字节与搜索词的第一个字符不匹配,则继续下一个字节。如果匹配,现在您正在寻找序列中的下一个字符。即,你的状态从0变为1.如果你的状态等于(或传递)搜索字符串的长度,你就找到了它!

执行/调试留给读者。

答案 2 :(得分:0)

有专门的算法,但我们先试试一个简单的算法。

您可以在阅读下一个字节后立即开始进行比较。一旦你这样做,很容易发现你不需要保留任何早于最长模式的字节。

因此,您可以使用与最长模式一样长的缓冲区,将新字节放在一端并将其放在另一端。

正如我所说,算法比这更有效,但它是一个良好的开端。

答案 3 :(得分:0)

使用FileInputStream包裹的BufferedInputStream并比较每个字节。将缓冲区保持为您正在寻找的序列的长度,以便在某些时候它不匹配时回溯。如果您要查找的序列太大,您可以保存偏移量并重新打开文件以供阅读。

或者,如果您只想复制和粘贴某些内容,可以查看this SO question