mmap big endian vs. little endian

时间:2009-06-22 06:48:36

标签: mmap endianness

如果我使用mmap来编写uint32_t,我是否会遇到大端/小端约定的问题?特别是,如果我在大端机器上编写一些数据mmap,当我尝试在小端机器上读取数据时会遇到问题吗?

2 个答案:

答案 0 :(得分:5)

如果你正在使用mmap,你可能会担心速度和效率。你基本上有几个选择。

  1. 用htonl,htons,ntohl,ntohs函数包装所有读写。在Windows上调用htonl(主机到网络)顺序会将数据从little endian转换为big endian。在其他架构上它将是一个noop。这些转换确实有一些开销,但根据您的操作,它们可能会或可能不会很重要。 AFAIK,这是SQLite使用的方法
  2. 您的另一个选择是始终以主机格式写入数据,并在用户需要跨平台迁移数据时提供例程。数据库通常以主机格式读写数据,但提供bcp等工具,它们将写入ASCII或网络字节顺序。
  3. 您可以使用字节顺序标记标记文件的标题。当您的程序启动时,它会将其字节顺序与文件的顺序进行比较,并在需要时提供任何转换。这通常适用于简单的数据格式(如UTF-16),但不适用于具有多种可变长度类型的格式。
  4. 此外,如果您执行提供长度前缀或文件偏移等操作,则可能混合使用32位和64位指针。 32位平台无法创建大于4GB的mmap视图,因此您不太可能支持大于4 GB的文件大小。像rrdtool这样的程序采用这种方法,并在64位平台上支持更大的文件大小。这意味着如果您使用文件内部的平台指针大小,则您的二进制文件将不能跨平台兼容。

    我的建议是预先忽略所有字节顺序问题,并将系统设计为在您的平台上快速运行。如果/当您需要将数据移动到另一个平台时,请选择最简单/最快/最合适的方法。如果你开始尝试创建一个独立于平台的数据格式,你通常会犯错误,并且必须回过头来修复这些错误。当99%的数据处于正确的字节顺序时,这尤其成问题,并且1%的数据是错误的。这意味着修复数据转换代码中的错误将破坏所有平台上的现有客户端。

    在编写代码以支持多个平台之前,您需要进行多平台测试设置。

答案 1 :(得分:2)

mmap将原始文件数据映射到进程地址空间。它不知道原始数据代表什么,更不用说尝试为你转换它。如果要在具有不同字节序的体系结构上映射相同的文件,则必须自己进行任何必要的转换。

作为跨计算机的可移植数据格式,我会考虑一些更高的抽象级别,例如JSON甚至XML,它们不会将数据格式与特定实现联系起来。但这实际上取决于您的具体要求。