如何在C++中从二进制文件中删除零件
How to delete parts from a binary file in C++
我想使用C++从二进制文件中删除部分。二进制文件大约为5-10 MB。
我想做的事:
- 搜索ANSI字符串"something"
- 找到这个字符串后,我想删除下面的n个字节,例如下面的1MB数据。我想删除这些字符,而不是用NULL填充它们,从而使文件更小
- 我想把修改后的文件保存到一个新的二进制文件中,除了我删除的丢失的n个字节之外,它和原始文件一样
你能给我一些如何最有效地做到这一点的建议/最佳实践吗我应该先将文件加载到内存中吗?
如何有效地搜索ANSI字符串我的意思是,在找到那个字符串之前,我可能必须跳过几兆字节的数据。>>有人告诉我应该在另一个问题中问它,所以它在这里:如何在二进制文件中查找ANSI字符串?
如何有效地删除n个字节并将其写入新文件
好吧,我不需要它是超高效的,文件不会大于10MB,如果它运行几秒钟就可以了。
有许多快速字符串搜索例程的性能比测试每个字符要好得多。例如,当试图找到"某物"时,只需要测试每9个字符。
下面是我为前面的一个问题写的一个例子:代码审查:查找<身体>在非null终止字符str 上进行标签反向搜索
对于一个5-10MB的文件,如果你的系统支持的话,我会看看writev()。因为它足够小,所以把整个文件读入内存。扫描要丢弃的字节。向writev()传递iovec列表(它将只是读取缓冲区和长度的指针),然后您可以在一个系统调用中重写整个修改后的内容。
首先,如果我理解你在"如何高效搜索"小节中的意思,那么如果目标字符串可能在前几兆字节中,你就不能跳过搜索中的几兆字节数据。
至于将文件加载到内存中,如果你这样做了,不要忘记确保内存中有足够的空间容纳整个文件。如果你去使用你的实用程序,发现你想使用的2GB文件无法容纳你剩下的1.5GB内存,你会感到沮丧。
我假设您将把它加载到内存或内存映射中,以进行以下操作。
你确实明确表示这是一个二进制文件,所以这意味着你不能使用普通的C++字符串搜索/匹配,因为文件数据中的null字符会混淆它(过早结束而没有匹配)。相反,您可以使用memchr查找目标中第一个字节的第一个出现,并使用memcmp将接下来的几个字节与目标中的字节进行比较;继续使用memchr/memcmp对扫描整个东西,直到找到为止。这不是最有效的方法,因为有更好的模式匹配算法,但我认为这是一种有效的方法。
要"删除"n个字节,您必须实际将数据移动到这n个字节之后,将整个数据复制到新位置。
如果您真的将数据从磁盘复制到内存,那么在那里操作数据并写入新文件会更快。否则,一旦在磁盘上找到要开始删除的位置,就可以打开一个新文件进行写入,从第一个文件读取X个字节,其中X是指向第一个文件的文件指针位置,并将它们直接写入第二个文件,然后在第一个文件中查找X+n,并从那里到file1的eof执行同样的操作,将其附加到已经放入file2的内容中。
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 如何在C++中从二进制文件中删除零件