2009-06-22 81 views
2

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

回答

2

是的。

mmap映射原始文件数据以处理地址空间。它不知道什么是原始数据,更不用说为你转换它。如果您在具有不同字节顺序的体系结构上映射相同的文件,则必须自己进行必要的转换。

作为一种跨计算机的便携式数据格式,我会考虑具有更高抽象层次的东西,比如JSON甚至是XML,它不会将数据格式与特定实现绑定。但它确实取决于您的具体要求。

5

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

  1. 用htonl,htons,ntohl,ntohs函数包装所有的读写操作。在Windows上调用htonl(主机到网络)命令会将数据从小端转换为大端。在其他架构上,这将是一个noop。这些转换确实存在开销,但取决于您的运营情况,它们可能很重要,也可能不重要。 AFAIK,这是SQLite使用的方法
  2. 您的其他选择是始终以主机格式写入数据,并在用户需要跨平台迁移数据时提供例程。数据库通常以主机格式读写数据,但提供像bcp这样的工具,可以写入ASCII或网络字节顺序。
  3. 您可以使用字节顺序标记标记文件的标题。当你的程序启动时,它会将它的字节顺序与文件的字节顺序进行比较,并在需要时提供任何翻译。对于简单的数据格式(如UTF-16)而言,这通常很有用,但对于具有多种可变长度类型的格式不适用。

此外,如果您要做的事情如提供长度前缀或文件偏移量,则可能会混合使用32位和64位指针。 32位平台无法创建大于4GB的mmap视图,因此您不太可能支持大于4 GB的文件大小。像rrdtool这样的程序采用这种方法,并在64位平台上支持更大的文件大小。这意味着如果您在文件中使用了平台指针大小,那么您的二进制文件将不会跨平台兼容。

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

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

+0

除了我们确定英特尔字节排序是最自然的数据存储方式之外,我们有类似的问题:几乎所有客户都运行Linux(Intel)服务器或Windows(当然是英特尔)服务器。大端已经过时了。 – 2009-09-10 01:17:21