【问题标题】:Handling endianness when reading from a byte array in C?从C中的字节数组读取时处理字节顺序?
【发布时间】:2013-02-16 03:55:50
【问题描述】:

我有一个字节数组的数据,应该是跨平台一致的。假设我有一个指针unsigned char* data,它指向我数组中的某个位置,我想将 4 个字节读入一个变量。我认为我可以这样做:

uint32_t my_int = *data;

但是,我意识到该方法不考虑字节序。例如,如果我的数据是大端的,我是否必须这样做才能一致地读取它?

uint32_t my_int = (data[0] << 3) + (data[1] << 2) + (data[2] << 1) + data[3];

同样,在使用fwrite 写入此数据时,我是否必须进行相同的检查?例如,如果我使用以下代码将相同的数据写入文件:

fwrite(&my_int, sizeof(my_int), 1, fh);

生成的数据是否有任何已知的字节顺序?或者它会依赖于架构?如果是这样,在所有平台上进行这些读取和写入并强制执行特定字节顺序的最简单方法是什么?

【问题讨论】:

  • Byte 数组没有字节序...
  • @vonbrand 好吧,显然,他们当然不会,但问题是操作 with 该数组是否会受到平台字节序的影响。
  • 你想做什么?如果它只是一个字节数组,那么字节序就不会成为问题。您是否尝试将 4 个字节作为整数读取?
  • 如果您将字节存储到unsigned int(或其他非chars)中,字节序定义存储假定的值。如果您不将它们发送到其他地方,您将是安全的。要么坚持字节数组,要么小心使用htonl(3)的部落。

标签: c io endianness


【解决方案1】:

在读取或写入二进制数据时,您需要担心字节顺序。如果您尝试读取/写入整个结构,您还需要担心可变大小和可能的结构打包。有些架构也无法处理奇变量边界上的整数,因此您不能直接使用 uint32_t myInteger = *(uint32_t*)bufferPtr++ 从二进制缓冲区中获取整数。

有各种各样的方法可以使这项工作。在过去,当速度和 RAM 使用是非常重要的问题时,我们会直接从文件中读取大量数据到缓冲区中,然后在需要时使用指向结构的指针来修复字节顺序。

今天你仍然可以这样做,尽管编译器之间的结构包装差异使它很麻烦,所以为特定类型编写一些简单的 i/o 例程可能更有意义,例如

int write_integer_at_position( FILE *, size_t position, uint32_t );
int read_integer_from_position( FILE *, size_t position, uint32_t *outResult );
etc

如果需要,这些例程会在读取数据之后或将数据写入磁盘之前交换字节,可能使用 htonl。完成 20 或 30 次后,您可能想要编写某种数据描述语言来映射 RAM 和文件中的结构。很多人都这样做了,但我认为没有一个人真正流行起来。

【讨论】:

    【解决方案2】:

    如果使用整数,则有一系列函数/宏

    例如ntol

    至于打包 - 只需定义一个协议和应该放置的东西。然后 write 可以构造一个字符数组,其中各个位位于正确的位置。这应该对应于检索这些详细信息的代码。

    【讨论】:

      【解决方案3】:

      这些是您在数据流出或进入您的应用程序时面临的典型问题。如果数据的生产者和消费者只是您的应用程序,那么问题就不大了。

      但是,正如 EricS 所提到的,如果还有其他应用程序将使用或生成这些数据,并且这些应用程序位于不同的平台/语言/框架上,那么序列化或反序列化的字节顺序肯定很重要。

      网络顺序是一种用于基于 IP 的协议的事实上的标准。有一些库函数可以从主机转换到网络和从网络到主机命令(参见 Ed Heal 提供的链接)。

      除了字节顺序之外,您可能还需要查看位顺序,根据协议和平台,最高有效位或最低有效位可能首先在线路上被推出。

      可能还需要考虑结构的封装、类型(整数、字符串、字符)的表示、大小等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多