在缓冲区中加载块的大二进制文件中搜索

search in a big binary file loading blocks in buffer

本文关键字:二进制文件 搜索 缓冲区 加载      更新时间:2023-10-16

我想知道按块搜索大文件的算法,并将它们加载到内存缓冲区中。

所以我有一个很大的文件,会把它读到小缓冲区并扫描它以查找"针"字:

while ( read = fread(buff, buff_size, 1, file) )
   if strstr(buff, needle) print "found!";

但是,如果"干草"中的"针"会被块边界切断怎么办?不可能找到。

我看到的一种解决方案是每次都读取下一个块(减少"针"字符串长度的偏移)

 offset += read - strlen(needle);
 if (offset > 0) fseek(file, offset ,SEEK_SET);

我说的对吗?

您是对的,您需要处理搜索模式跨越两个块的情况。

你也是对的,寻求可以是一种解决方案。

但是还有其他不使用搜索的解决方案。

解决方案 1

一种解决方案可能是复制缓冲区的最后一部分,即 strlen(needle)到一个能够容纳 2 倍strlen(needle)的小缓冲区。

然后,当读取下一个块时,您将新缓冲区的第一部分(再次strlen(needle))复制到小缓冲区,以便它与前一个缓冲区末尾的部分污染。

最后,您可以在小缓冲区中搜索niddle。

解决方案 2

一个解决方案是从文件读取到buffer + strlen(needle),即避免覆盖缓冲区的前strlen(needle)个字符。从文件中读取的字符数必须相应减少(即 buff_size - strlen(needle)

使用缓冲区完成后,将最后 strlen(needle) 个字符复制到缓冲区的开头,并将文件中的更多数据读取到buffer + strlen(needle)

对于缓冲区中的第一次搜索,您必须跳过前 strlen(needle) 个字符(或确保它们与您的模式不匹配,例如通过初始化)。随后的检索应检索整个缓冲区。