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