对 STL 字符串使用 fread/fwrite。这是正确的吗?
Posted
技术标签:
【中文标题】对 STL 字符串使用 fread/fwrite。这是正确的吗?【英文标题】:Using fread/fwrite for STL string. Is it correct? 【发布时间】:2011-07-21 20:52:19 【问题描述】:我有一个包含字符串的结构。类似的东西:
struct Chunk
int a;
string b;
int c;
;
所以,我想,我不能使用 fread 和 fwrite 函数从文件中读写这个结构。因为字符串可能会保留不同的内存容量。 但是这样的代码可以正常工作。
Chunk var;
fwrite(&var, sizeof(Chunk), 1, file);
fread(&var, sizeof(Chunk), 1, file);
真的有问题吗?
【问题讨论】:
【参考方案1】:你有理由怀疑这一点。您应该只使用 fwrite
和 fread
流式传输 POD 类型,而 string
不是 POD
。
【讨论】:
除此之外,指针是POD,但一般都不好序列化。 谢谢@Ben,我的术语很松散。 而且您仍然需要警惕 POD 类型的对齐问题。对于struct suint8_t c; uint64_t d;
sizeof(struct s)
可能不是9。【参考方案2】:
你不应该这样做,因为不同的实现使用不同的std::string
结构。
一般来说,你应该只序列化整数类型、布尔类型、二进制数据(如果你可以称之为序列化)。如果您考虑在平台之间共享序列化数据,请务必使用一种字节序。
注意浮点数、双精度数和指针。他们会变得非常讨厌。
您也必须小心 C/C++ 结构,因为它们可能包含不可预测的填充量。
【讨论】:
即使是结构体也是一个问题,因为它们包含不可预测的填充量。如果您在写入数据的同一程序和进程中读取数据可能没问题,但这绝对不是可移植的。您确实必须递归地单独序列化结构成员。【参考方案3】:你应该序列化数据。
您可能希望手动执行此操作 - 当涉及到 std::string
时,请查看:
const charT* std::string::c_str() const
const charT* std::string::data() const
当涉及到更复杂的对象时,您可能会对things like Google Protocol Buffers and/or Thrift 感兴趣。
【讨论】:
以上是关于对 STL 字符串使用 fread/fwrite。这是正确的吗?的主要内容,如果未能解决你的问题,请参考以下文章
fread/fwrite 将 size 和 count 作为参数的理由是啥?