C++如何使用ofstream打开二进制文件时不启用ios::trunc模式修改局部内容
问题根因
你第二次打开文件时仅使用了ios::out | ios::binary参数,C++标准规定单独使用ios::out打开已存在的普通文件时,默认会启用ios::trunc(截断)逻辑,直接清空文件全部原有内容,因此你第一次写入的内容被直接清除,seekp到第4字节写入时,前面的位置自然会被填充为空字节。
解决方法
不需要把整个文件读入内存修改再回写,只要调整第二次打开文件的参数即可:
- 追加
ios::in标志,即使你不需要读取文件内容,只要同时指定ios::in和ios::out,打开已存在文件时就不会默认清空原有内容,支持随机位置写入。 - 额外修正你原有代码的一处错误:
sizeof(someThing)取到的是std::string对象本身的栈内存大小,不是字符串的实际长度,应该替换为someThing.size()才能正确写入全部字符串内容。
修正后的代码
#include <fstream> #include <string> using namespace std; int main() { string fileName = "fileName.bin", someThing = "something", otherThing = "otherthing"; fstream file; // 第一次写入:创建文件写入初始内容 file.open(fileName, ios::out | ios::binary); file.write(someThing.c_str(), someThing.size()); file.close(); // 第二次修改:原地修改文件指定位置内容,无需全量读写 file.open(fileName, ios::in | ios::out | ios::binary); // 关键修改:增加ios::in参数 file.seekp(4); file.write(otherThing.c_str(), otherThing.size()); file.close(); return 0; }
运行后文件内容就是你预期的someotherthing,符合需求。如果需要兼容第二次打开时文件可能不存在的场景,可以先判断文件是否存在,不存在时先创建空文件,再用上述参数打开即可。
内容的提问来源于stack exchange,提问作者kevin256
相关产品推荐
相关产品推荐

