如何在C ++中从二进制文件中删除部件

时间:2011-06-22 23:22:18

标签: c++ search replace binaryfiles ifstream

我想使用C ++从二进制文件中删除部分。二进制文件大约是5-10 MB。

我想做什么:

  1. 搜索ANSI字符串“something”
  2. 一旦找到此字符串,我想删除以下n个字节,例如以下1 MB的数据。我想删除那些字符,而不是用NULL填充它们,从而使文件变小。
  3. 我想将修改后的文件保存到一个新的二进制文件中,与原始文件相同,除了我删除的缺少的n个字节。
  4. 你能否给我一些建议/最佳实践如何最有效地完成这项工作?我应该先将文件加载到内存中吗?

    如何有效地搜索ANSI字符串?我的意思是在找到该字符串之前我可能必须跳过几兆字节的数据。 >>我被告知我应该在另一个问题中问它,所以它在这里: How to look for an ANSI string in a binary file?

    如何有效删除n个字节并将其写入新文件?

    好的,我不需要它超级高效,文件不会超过10 MB,如果运行几秒钟就可以。

3 个答案:

答案 0 :(得分:1)

有许多快速字符串搜索例程比测试每个字符要好得多。例如,当试图找到“某物”时,只需要测试每个第9个字符。

以下是我为之前的问题撰写的一个示例:code review: finding </body> tag reverse search on a non-null terminated char str

答案 1 :(得分:0)

对于5-10MB的文件,如果您的系统支持,我会查看writev()。将整个文件读入内存,因为它足够小。扫描要删除的字节。将writev()传递给iovecs列表(它只是指向读缓冲区和长度的指针)然后你可以在一个系统调用中重写整个修改过的内容。

答案 2 :(得分:0)

首先,如果我在“我如何有效搜索”小节中理解了你的意思,那么如果目标字符串可能只有前几兆字节,你就不能在搜索中跳过几兆字节的数据。

至于将文件加载到内存中,如果这样做,请不要忘记确保内存中有足够的空间用于整个文件。如果你去使用你的工具并发现你想要使用它的2GB文件不能适合你剩下的1.5GB内存,你会感到沮丧。

我将假设您将加载到内存或内存中映射以下内容。

你明确地说这是一个二进制文件,所以这意味着你不能使用正常的C ++字符串搜索/匹配,因为文件数据中的空字符会混淆它(过早地结束它而没有匹配)。您可以使用memchr来查找目标中第一个字节的第一个字节,并使用memcmp将接下来的几个字节与目标中的字节进行比较;继续使用memchr / memcmp对扫描整个事物直到找到。这不是最有效的方法,因为有更好的模式匹配算法,但我认为这是一种有效的方式。

要“删除”n个字节,您必须在这n个字节后实际移动数据,将整个内容复制到新位置。

如果您实际上将数据从磁盘复制到内存,那么在那里操作它并写入新文件会更快。否则,一旦在磁盘上找到要从中开始删除的位置,就可以打开一个新文件进行写入,从第一个文件读取X个字节,其中X是第一个文件中的文件指针位置,然后写入它们直接进入第二个文件,然后搜索到第一个文件到X + n并从那里到file1的eof做同样的事情,将其附加到你已经放入file2的文件中。