【问题标题】:Alternatives to fread and fwrite for use with structured data用于结构化数据的 fread 和 fwrite 的替代方案
【发布时间】:2010-03-28 04:39:49
【问题描述】:

这本书Beginning Linux Programming (3rd ed)

“请注意,不建议将 fread 和 fwrite 用于结构化数据。部分问题是使用 fwrite 写入的文件可能无法在不同机器之间移植。”

这到底是什么意思?如果我想编写一个可移植的结构化数据读取器或写入器,我应该使用哪些调用?直接系统调用?

【问题讨论】:

    标签: c portability


    【解决方案1】:

    这本书明智地警告不要将文件中的字节块直接读取到数据结构中。

    这样做的问题是,数据结构的各个元素之间可能存在未命名的填充字节,而这些字节的数量和位置完全取决于实现。

    您仍然可以使用freadfwrite 调用从文件中读取和写入数据,但是您应该单独读取和写入数据结构的每个元素,而不是在以下位置读取或写入整个结构一次。

    您还需要牢记其他一些可移植性问题。例如,各种数字类型具有依赖于实现的大小。为了可移植性,您可以使用stdint.h 标头中定义的类型。

    浮点和无符号整数表示也可能存在差异,但大多数系统和文件格式现在分别使用 IEEE 754 和二进制补码,因此这些类型的兼容性问题要少得多。只要确保你知道你的规格是什么。

    【讨论】:

    • 非常感谢。似乎与 fread 或 fwrite 无关,因为据我所知,数据结构总是依赖于实现来填充。在谈论 fread 或 fwrite 等特定调用时强调这个问题是否很奇怪?
    • @forest:正是因为 fread/fwrite 不知道使用它们可能会失败的填充。例如,给定struct A { int i; char c; };,您需要两个 fread 调用(ic 各一个)而不是一个(整个结构)。关于可移植整数类型的要点是,您不必依赖int 使用的特定位数(可能因平台甚至编译器设置而异)。
    【解决方案2】:

    数据序列化是您感兴趣的主题。

    这与变量的大小有关,与编码有关(字符串可能是 utf-8、utf16... 等),与字节序(BigEndian、LowEndian)有关。

    对于便携式解决方案I would recommend you to take a look at Google ProtocolBuffers and Thrift

    【讨论】:

      【解决方案3】:

      如果您担心portability 的数据,您应该查看Serialization 技术和库,特别是s11n JSON YAML XDR ASN1 Jansson XML等等

      问自己几年后的数据和应用程序?...

      文本表示通常不如二进制表示“脆弱”。

      【讨论】:

        猜你喜欢
        • 2018-03-12
        • 1970-01-01
        • 2012-09-28
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        相关资源
        最近更新 更多