一个外部小组为我提供了在 Big Endian 机器上编写的文件,他们还为文件格式提供了 C++ 解析器。
我只能在小端机器上运行解析器 - 有没有办法使用他们的解析器读取文件而不在每次读取后添加 swapbytes() 调用?
一个外部小组为我提供了在 Big Endian 机器上编写的文件,他们还为文件格式提供了 C++ 解析器。
我只能在小端机器上运行解析器 - 有没有办法使用他们的解析器读取文件而不在每次读取后添加 swapbytes() 调用?
早在铁器时代早期,古人在尝试将原始 PDP-11 小型计算机与其他原始计算机联网时遇到了这个问题。PDP-11 是第一台 little-Endian 计算机,而当时大多数其他计算机都是 big-Endian。
为了解决这个问题,他们一劳永逸地开发了网络字节序概念(总是 big-Endia),以及相应的网络字节序宏 ntohs()、ntohl()、htons() 和 htonl()。用这些宏编写的代码总是会“得到正确的答案”。
依靠您的外部供应商在他们的代码中使用宏,他们提供给您的文件将始终是 big-Endian,即使他们切换到 little-Endian 机器。重写他们提供给您的解析器以使用宏,即使您切换到大端机器,您也将始终能够读取他们的文件。
大量的程序员时间已经浪费在这个特定的问题上。有时候,我认为吊死做出 little-Endian 功能决定的 PDP-11 设计师是一个很好的论据。
尝试说服解析器团队包含以下代码:
int getInt(char* bytes, int num) { 诠释; 断言(数字 == 4); ret = 字节[0] << 24; ret |= 字节[1] << 16; ret |= 字节[2] << 8; ret |= 字节[3]; 返回 ret; }
它可能比一般的更耗时,int i = *(reinterpret_cast<*int>(&myCharArray));
但在大端和小端系统上总是能得到正确的字节序。
这取决于您对数据的处理方式。如果要打印数据,则需要交换所有数字上的字节。如果您在文件中查找一个或多个值,则对比较值进行字节交换可能会更快。
一般来说,格雷格是正确的,你必须努力去做。
一般来说,对此没有“简单”的解决方案。您将不得不修改解析器以交换从文件中读取的每个整数的字节。
最好的方法是只定义文件格式的字节序,而不是说它依赖于机器。无论在哪个 CPU 上运行,写入器都必须以正确的顺序写入字节,而读取器也必须这样做。
如果您不想修改他们的解析器,您可以编写一个解析器来包装他们的解析器并反转字节。
注意读入的数据类型。4 字节int
或float
需要字节序校正。4 字节的 ASCII 字符串不会。
一般来说,没有。
如果读/写调用不是类型感知的(例如 fread 和 fwrite 不是),那么他们无法区分写入字节序敏感数据和字节序不敏感数据之间的区别。
根据解析器的结构,您可能能够避免一些痛苦,如果他们使用的 I/O 函数知道正在读取/写入的类型,那么您可以修改这些例程应用正确的字节序转换。
如果您确实必须修改所有读/写调用,那么创建这样的例程将是一个明智的做法。
你的问题不知何故包含了答案:不!
我只能在小端机器上运行解析器 - 有没有办法使用他们的解析器读取文件而不在每次读取后添加 swapbytes() 调用?
如果您在小端机器上读取(并想解释)大端数据,则必须以某种方式在某处转换数据。您可以在每次读取或读取整个文件后执行此操作(如果读取的数据不包含有关如何读取更多数据的任何信息) - 但无法省略转换。