对 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】:

你有理由怀疑这一点。您应该只使用 fwritefread 流式传输 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 作为参数的理由是啥?

fread/fwrite实现复制功能

56.fread fwrite

fread(),fwrite() 读/写流

Linux read/write fread/fwrite两者区别

C 语言文件操作 ( fwrite 函数 )