【问题标题】:Moving binary files between big endian and little endian platforms在大端和小端平台之间移动二进制文件
【发布时间】:2021-12-25 21:45:05
【问题描述】:

我知道无论主机字节序如何,网络字节顺序都是大字节序。

我的问题是当二进制文件从 BE 平台移动到 LE 平台时会发生什么。 从这篇文章我可以看到磁盘上的数据字节顺序与平台的内存字节顺序相同: https://stackoverflow.com/a/5751824

所以假设我在 LE 机器上有一个小的二进制文件,其内容按 LE 顺序 2 5: (注意我已经用xxd把它变成了一个实际的二进制文件)

00000010 00000101
  • 使用 wget 在 BE 机器上下载此文件。
  • 签出文件内容仍然是00000010 00000101

在传输之前文件不是必须反转为00000101 00000010吗?如果是这样的话 BE机器收到后不会按网络顺序存储它吗?下载后文件内容怎么不反转?

【问题讨论】:

  • 网络字节序是网络字节序,不是大端也不是小端。它是网络字节顺序。然后,您将了解外设如何将该数据包数据映射到处理器的地址空间或将数据复制到某处的内存中。然后是架构和访问类型/大小。那么术语大端至少有不同的定义,你可以让大端不以你认为网络流中的 0x11、0x22、0x33、0x44 可以是 0x11223344 或 0x44332211 的方式访问网络字节顺序数据取决于处理器的大端序...
  • 使用并尝试将事物隔离到字节序桶中往往会比成功带来更多的痛苦。而是做你的系统工程。数据是如何进入外设的,它是如何或可以呈现给处理器的,处理器通过模式或指令访问选项/功能是什么,等等。这些都不需要术语字节序。
  • 文件就是文件,就像上面的语句一样,一件事与另一件事无关,文件是位或字节的序列,正确的传输将通过任何介质(网络,无线、硬盘到拇指驱动器、光驱等)到其他机器的硬盘驱动器/ssd,与操作系统、操作系统版本、文件系统类型、处理器架构等无关。
  • 网络本身的物理接口不是固定的,每种技术都有一种(如果不超过一种)方式将比特切碎并通过媒体发送它们然后将它们重新组合在一起,只是有多个层在物理层内,不包括也涉及的教科书网络层本身。然后在这些网络层之上,你有文件层和操作系统等,以确保文件在理想情况下,一点一点地显示出来。
  • 然后是程序员的工作,最好不要使用字节序来读/写文件。做你的系统工程,不要仅仅假设 BE 或 LE 意味着任何相关的东西,因为它没有。犯下跨编译域使用结构的主要罪行会导致字节序问题。如果需要和更便携的代码,可以轻松避免和无字节序。

标签: networking cpu-architecture endianness


【解决方案1】:

我的问题是当二进制文件从 BE 平台移动到 LE 平台时会发生什么。

文件字节应该被复制而不被交换 - 字节应该在所有机器上以相同的顺序出现,逐字节详细说明。

对于简单的文本无关紧要,因为单个字节的序列本质上不是字节序。

对于大多数其他内容,将有一个已定义的文件格式,它指定大于 8 位的数字字段的字节顺序。这是您已经观察到的有关 TCP/IP 的内容,它为标头定义了大端。

JPG、PNG,其他要么避免使用多字节数字,要么定义在使用多字节数值时如何解释文件中的字节。

某些数据格式将使用字节顺序标记BOM,它是允许编写者选择字节序的灵活格式的一部分(因此,如果需要,可以选择适合写入系统的一种),并且,这允许读者确定文件的字节顺序。

对于多字节文本,Unicode 使用了上述一些特性,但更现代的编码 UTF-8 应该被解释为“简单”的字节序列(而不是多字节数字)并且不会不需要 BOM 或字节序概念。

【讨论】:

  • 谢谢,所以我编辑了我的问题以使其更加清晰,我使用xxd 将其转换为实际的二进制文件。所以我实际上是在传输一个 2 字节的二进制文件。没有标头或元数据,实际上只有 2 个字节。
  • @Dan,我的回答适用于任何文件,无论大小为 0、1、2 还是更多字节。
  • 所以我猜没有任何标题或元数据,我的文件被视为简单文本文件而不被交换?
  • 无论有无标题,字节都应该按照它们在源机器上出现的顺序进行复制。文件格式决定了字节在磁盘上的外观。 (或确定它们在网络上的外观的网络格式。)由读取系统(以及写入系统)来遵守规范。
  • 是的,一个文件的字节被发送到另一台计算机,就像一个接一个的一样,在两台机器上以相同的顺序存储为一个字节文件。通常由应用程序来正确解释文件的格式,如果这意味着由于不匹配而导致字节交换,那么应用程序必须这样做。
【解决方案2】:

内存被组织成一个字节序列在两个端,所以数据只是一个字节序列,例如 ASCII 或 UTF8,没有问题。当 2 个或 4 个或 8 个字节的组被解释为数字时,问题就开始了,此时您需要定义组中的第一个或最后一个字节是最不重要的。这就是大端和小端的区别。

如果您用 UTF-16 表示文本,其中文本被编码为 2 字节值的序列,那么字节序很重要,实际上 UTF-16 的一部分是在开头插入的零宽度不间断空格以指示字节顺序。

【讨论】:

  • 谢谢,但我忘了说这不是文字。我使用xxd 将其转换为实际的二进制文件。所以我实际上是在传输一个 2 字节的二进制文件。你并没有真正回答我的问题。
  • @Dan:如果您正确使用xxd,文件不会被字节交换或以其他方式混乱。
  • @PeterCordes 实际上并没有,我从上面的答案中了解到,并非每次传输都使用 BE 顺序的字节完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 2010-09-11
相关资源
最近更新 更多