【发布时间】:2019-01-10 23:01:50
【问题描述】:
我正在创建具有以下格式的记录的二进制文件:
quantity-of-records
record_1
record_2
...
record_N
问题是record_1 每次都被覆盖,而不是追加。
在 BOF 写入后在 EOF 写入
这是我的简化代码:
#include <fstream>
#include <string>
struct Record
{
unsigned int id;
std::string text;
};
int main()
{
static const Record table[] =
{
{
1, "Apple"
},
{
2, "Salt"
},
{
3, "Margarine"
},
{
4, "Carrot"
},
{
5, "Plum"
}
};
static const size_t records_in_table =
sizeof(table) / sizeof(table[0]);
static const char table_filename[] = "record_file.bin";
size_t i;
size_t record_quantity = 1u;
for (i = 0u; i < records_in_table; ++i)
{
std::ofstream table_file(table_filename,
std::ios::binary);
table_file.seekp(0, std::ios::beg);
table_file.write(reinterpret_cast<char *>(&record_quantity),
sizeof(record_quantity));
table_file.flush();
table_file.seekp(0, std::ios::end);
table_file.write(reinterpret_cast<char const *>(&table[i].id),
sizeof(Record::id));
const size_t length(table[i].text.length());
table_file.write(reinterpret_cast<char const *>(&length),
sizeof(length));
table_file.write(table[i].text.c_str(),
length);
table_file.close();
++record_quantity;
}
return 0;
}
这是二进制文件的内容:
$ od -Ax -x record_file.bin
000000 0005 0000 0000 0000 0005 0000 0004 0000
000010 0000 0000 6c50 6d75
000018
数字以 Little Endian 格式写入,32 位(4 字节) 64 位(8 字节)。
文本“Plum”的 ASCII 编码为:0x50, 0x6C, 0x75, 0x6D
这是第一次迭代后的二进制文件:
$ od -Ax -x record_file.bin
000000 0001 0000 0000 0000 0001 0000 0005 0000
000010 0000 0000 7041 6c70 0065
000019
环境/工具:
- 编译器:Visual Studio 2017、G++ (GCC) 7.4.0 (Cygwin)
- 操作系统:Windows 7
以app模式打开
另一种方法是以ios::app 模式打开文件,写入新记录,然后更新记录数量:
size_t i;
size_t record_quantity = 1u;
bool first_write(true);
for (i = 0u; i < records_in_table; ++i)
{
std::ofstream table_file(table_filename,
std::ios::binary | std::ios::app);
if (first_write)
{
first_write = false;
table_file.write(reinterpret_cast<char *>(&record_quantity),
sizeof(record_quantity));
table_file.flush();
table_file.write(reinterpret_cast<char const *>(&table[i].id),
sizeof(Record::id));
const size_t length(table[i].text.length());
table_file.write(reinterpret_cast<char const *>(&length),
sizeof(length));
table_file.write(table[i].text.c_str(),
length);
}
else
{
table_file.write(reinterpret_cast<char const *>(&table[i].id),
sizeof(Record::id));
const size_t length(table[i].text.length());
table_file.write(reinterpret_cast<char const *>(&length),
sizeof(length));
table_file.write(table[i].text.c_str(),
length);
table_file.flush();
table_file.seekp(0, std::ios::beg);
table_file.write(reinterpret_cast<char *>(&record_quantity),
sizeof(record_quantity));
}
table_file.close();
++record_quantity;
}
但是,在替代实现中,记录数量或文件中的第一个整数不会更新。
这是二进制文件的内容:
$ od -Ax -x record_file.bin
000000 0001 0000 0000 0000 0001 0000 0005 0000
000010 0000 0000 7041 6c70 0165 0000 0000 0000
000020 0100 0000 0500 0000 0000 0000 4100 7070
000030 656c 0002 0000 0004 0000 0000 0000 6153
000040 746c 0002 0000 0000 0000 0003 0000 0009
000050 0000 0000 0000 614d 6772 7261 6e69 0365
000060 0000 0000 0000 0400 0000 0600 0000 0000
000070 0000 4300 7261 6f72 0474 0000 0000 0000
000080 0500 0000 0400 0000 0000 0000 5000 756c
000090 056d 0000 0000 0000 0000
000099
问题:如何将记录附加到文件末尾并更新第一个整数(在文件开头)?
【问题讨论】:
标签: c++ file-io binaryfiles ofstream random-access