最近数据结构实践课经常需要进行二进制文件读写,总结出以下经验:
1. 读写二进制文件最好加上ios::binary
2. 二进制文件用fstream读写时既可以输入又可以输出,此模式下可以实现只修改文件部分内容
例如,我创建了含有100个数的二进制文件data_unsorted.dat,生成结果如下:
写入如下代码(ios::in不能少)
file.open("data_unsorted.dat", ios::binary | ios::in | ios::out);
int a[5] = { 778,2316, 3035, 2190, 1842 };
file.seekp(0, ios::beg);
file.write((char*)a, sizeof(a));
file.close();
二进制文件变为:
可以看到,二进制文件开头的5个数发生了改变,其余部分没有变化。
接着写入代码:
file.open("data_unsorted.dat", ios::binary | ios::in | ios::out);
file.seekp(32, ios::beg);
file.write((char*)a, sizeof(a));
file.close();
其中 file.seekp(32, ios::beg) 是从距离文件32字节的位置开始写入,此时二进制文件发生如下:
可以看到,文件从第9个数字开始发生了改变。因为我存储的数为int类型,每个数有4个字节,因此32字节后写入对应着第32/4=8个数后写入,即第9个数开始,印证了ios::in|ios::out写入不会覆盖二进制文件其他内容的猜想。
3. 如果写入二进制文件时只加入ios::out,那么写入的内容将覆盖原有文件;如果此时不是从文件起始处写入,那么光标到文件起始处的数字将会是全0。
例如,写入以下代码(注意没有ios::in)
file.open("data_unsorted.dat", ios::binary | ios::out);
file.seekp(20, ios::beg);
file.write((char*)a, sizeof(a));
file.close();
磁盘文件将发生以下变化:
可以看到,将a数组写入文件后,文件后面后面的内容将全部被清空,写入位置前的数字将全部变成0。