我想使用C ++从二进制文件中删除部分。二进制文件大约是5-10 MB。
我想做什么:
你能否给我一些建议/最佳实践如何最有效地完成这项工作?我应该先将文件加载到内存中吗?
如何有效地搜索ANSI字符串?我的意思是在找到该字符串之前我可能必须跳过几兆字节的数据。 >>我被告知我应该在另一个问题中问它,所以它在这里: How to look for an ANSI string in a binary file?
如何有效删除n个字节并将其写入新文件?
好的,我不需要它超级高效,文件不会超过10 MB,如果运行几秒钟就可以。
答案 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的文件中。