【发布时间】:2010-03-28 04:39:49
【问题描述】:
这本书Beginning Linux Programming (3rd ed)说
“请注意,不建议将 fread 和 fwrite 用于结构化数据。部分问题是使用 fwrite 写入的文件可能无法在不同机器之间移植。”
这到底是什么意思?如果我想编写一个可移植的结构化数据读取器或写入器,我应该使用哪些调用?直接系统调用?
【问题讨论】:
标签: c portability
这本书Beginning Linux Programming (3rd ed)说
“请注意,不建议将 fread 和 fwrite 用于结构化数据。部分问题是使用 fwrite 写入的文件可能无法在不同机器之间移植。”
这到底是什么意思?如果我想编写一个可移植的结构化数据读取器或写入器,我应该使用哪些调用?直接系统调用?
【问题讨论】:
标签: c portability
这本书明智地警告不要将文件中的字节块直接读取到数据结构中。
这样做的问题是,数据结构的各个元素之间可能存在未命名的填充字节,而这些字节的数量和位置完全取决于实现。
您仍然可以使用fread 和fwrite 调用从文件中读取和写入数据,但是您应该单独读取和写入数据结构的每个元素,而不是在以下位置读取或写入整个结构一次。
您还需要牢记其他一些可移植性问题。例如,各种数字类型具有依赖于实现的大小。为了可移植性,您可以使用stdint.h 标头中定义的类型。
浮点和无符号整数表示也可能存在差异,但大多数系统和文件格式现在分别使用 IEEE 754 和二进制补码,因此这些类型的兼容性问题要少得多。只要确保你知道你的规格是什么。
【讨论】:
struct A { int i; char c; };,您需要两个 fread 调用(i 和 c 各一个)而不是一个(整个结构)。关于可移植整数类型的要点是,您不必依赖int 使用的特定位数(可能因平台甚至编译器设置而异)。
数据序列化是您感兴趣的主题。
这与变量的大小有关,与编码有关(字符串可能是 utf-8、utf16... 等),与字节序(BigEndian、LowEndian)有关。
对于便携式解决方案I would recommend you to take a look at Google ProtocolBuffers and Thrift。
【讨论】:
如果您担心portability 的数据,您应该查看Serialization 技术和库,特别是s11n JSON YAML XDR ASN1 Jansson XML等等
问自己几年后的数据和应用程序?...
文本表示通常不如二进制表示“脆弱”。
【讨论】: