我正在尝试编写一个程序,它将读取非常大的二进制文件并尝试查找2个不同字符串的出现,然后打印与模式匹配的索引。为了示例,我们假设字符序列是[H,e,l,l,o]
和[H,e,l,l,o, ,W,o,r,l,d]
。
我能够为小二进制文件编写代码,因为我将每个字符作为一个字节读取,然后将其保存在Arraylist
中。然后从Arraylist
的开头开始,我将byte arraylist(byte[] data)
与byte[] pattern
进行比较。
我需要找到一种方法来做同样的事情,但不要将整个二进制文件写入内存中进行比较。这意味着我应该能够在阅读每个字符时进行比较(我不应该将整个二进制文件保存在内存中)。假设二进制文件只包含字符。
有关如何实现这一目标的任何建议?提前谢谢大家。
答案 0 :(得分:5)
好像你真的在寻找Aho-Corasick string matching algorithm。
该算法根据您拥有的给定字典构建自动机,然后允许您使用输入字符串的单次扫描查找匹配项。
维基百科文章链接到this java implementation
答案 1 :(得分:2)
谷歌“有限状态机”。
或者,一次读取一个字节的文件,如果该字节与搜索词的第一个字符不匹配,则继续下一个字节。如果匹配,现在您正在寻找序列中的下一个字符。即,你的状态从0变为1.如果你的状态等于(或传递)搜索字符串的长度,你就找到了它!
执行/调试留给读者。
答案 2 :(得分:0)
有专门的算法,但我们先试试一个简单的算法。
您可以在阅读下一个字节后立即开始进行比较。一旦你这样做,很容易发现你不需要保留任何早于最长模式的字节。
因此,您可以使用与最长模式一样长的缓冲区,将新字节放在一端并将其放在另一端。
正如我所说,算法比这更有效,但它是一个良好的开端。
答案 3 :(得分:0)
使用FileInputStream
包裹的BufferedInputStream
并比较每个字节。将缓冲区保持为您正在寻找的序列的长度,以便在某些时候它不匹配时回溯。如果您要查找的序列太大,您可以保存偏移量并重新打开文件以供阅读。
或者,如果您只想复制和粘贴某些内容,可以查看this SO question。