使用C或C ++在大型二进制文件中查找模式?

时间:2011-02-18 22:35:35

标签: c++ c file search design-patterns

我有一个~700 MB的二进制文件(非文本数据);我想要做的是搜索整个文件中随机位置发生的特定字节模式。例如0x? 0x? 0x55 0x? 0x? 0x55 0x? 0x? 0x55 0x? 0x? 0x55依此类推50个左右的字节。我要搜索的模式是两个随机字节的序列,每两个字节出现0x55。

也就是说,搜索存储在文件中的表,其中0x55是分隔符,然后保存表中包含的数据或以其他方式操纵它。

最好的选择是简单地一次遍历每个字节,然后向前看两个字节以查看值是否为0x55,如果是,则再次向前看以确认表存在在那个位置?

加载整个东西? FSEEK?缓冲区块,一次搜索那一个字节?

使用C或C ++查看此大文件并查找模式的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

对于regular expression匹配器或deterministic finite automaton来说,这听起来不错。这些是高功率工具,旨在满足您的需求,如果您拥有它们,那么您可以毫不费力地进行此类搜索。在C ++中,考虑查看Boost.Regex库,它们应具备解决此问题所需的所有功能。

答案 1 :(得分:1)

最终对我有用的是Boyer-Moore-Horspool算法(由Jerry Coffin建议)和我自己的基于表结构和存储数据的算法之间的混合。

基本上,BMH算法捕获了我正在寻找的大部分内容。显而易见的事情。

但是有些表确实有奇怪的格式化,我必须实现一个半智能搜索,它会查看每个0x55之后的数据,并弄清楚它是否可能是是好的数据,或者只是随机垃圾。

奇怪的是,我最终用PHP而不是C ++实现它,并将结果直接转储到MySQL数据库中进行查询。搜索过程只花了大约5分钟或更短时间,结果非常好。我最终得到了很多垃圾数据,但它抓住了我需要的所有东西,并且(据我所知)并没有留下任何好的数据。

答案 2 :(得分:0)

  

加载整个东西? FSEEK?缓冲区块,一次搜索那一个字节?

如果可以将整个内容加载到内存中,则应该使用平台提供的内存映射功能。这样,操作系统可以决定是否应该将文件的大部分保留在物理内存中(即系统目前有大量的空闲RAM),或者它是否应该只在较小的块中工作。

当然,只有在您可以将文件放入工作集时才能使用。