这不是特定于任何编程语言的问题。假设您在大端机器上编写了一些文件,并且您知道这一点。如果两个单字节值是背靠背写入的,你怎么知道?Big-endian 颠倒了 16、32 和 64 位值的顺序,那么您怎么知道需要将其作为单个字节读取呢?
例如,您写入字节 0x11,然后写入字节 0x22。然后该文件包含 0x1122。如果您在小端机器上阅读它,则必须对其进行转换。那么你会把它读成 2211 还是 1122?你知道怎么做吗?
这有道理吗?我觉得我在这里错过了一些超级基本的东西。
这不是特定于任何编程语言的问题。假设您在大端机器上编写了一些文件,并且您知道这一点。如果两个单字节值是背靠背写入的,你怎么知道?Big-endian 颠倒了 16、32 和 64 位值的顺序,那么您怎么知道需要将其作为单个字节读取呢?
例如,您写入字节 0x11,然后写入字节 0x22。然后该文件包含 0x1122。如果您在小端机器上阅读它,则必须对其进行转换。那么你会把它读成 2211 还是 1122?你知道怎么做吗?
这有道理吗?我觉得我在这里错过了一些超级基本的东西。
没有办法知道。这就是为什么正式指定的文件格式通常要求字节顺序,或者它们提供一个选项(如 MSN 所提到的 unicode)。这样,如果您正在读取具有特定格式的文件,您就知道它已经是大端序了,因为它采用该格式这一事实意味着特定的字节序。
另一个很好的例子是网络字节顺序——网络协议通常是大端的,所以如果你是一个与互联网通信的小端处理器,你必须倒着写。如果您是大端,则无需担心。人们使用htonl 和 ntohl之类的函数来预处理他们写入网络的内容,以便他们的源代码在所有机器上都是相同的。这些函数被定义为在大端机器上什么都不做,但它们在小端机器上翻转字节。
关键的实现是字节顺序是特定架构如何表示单词的属性。他们必须以某种方式编写文件不是强制性的。它只是告诉您体系结构上的指令期望多字节字以某种方式对其字节进行排序。big-endian 机器可以写入与 little-endian 机器相同的字节序列,它可能会使用更多指令来完成,因为它必须重新排序字节。对于编写大端格式的小端机器也是如此。
您需要预测它,因为您知道其他内容(即,您知道您正在读取大端格式的文件),或者您需要以某种方式对文件中的字节序进行编码。Unicode 文本文件使用0xFFFE
(或类似的东西)作为文本文件的前两个字节来计算字节顺序。如果您将其读取为 0xfffe,则它是本机字节序格式。如果您将其读为 0xfeff,则不是。
你是完全正确的......如果不知道你正在查看的数据,就无法知道。
话虽如此,通常有很多方法可以猜测...如果您知道应该看到文本,则可以运行一些简单的测试以查看您得到的内容是否合理...如果您可以阅读标题出来,您通常可以从中推断出它...但是如果您只是查看字节流,则没有万无一失的方法可以知道。
这有道理吗?
是的:这是个问题。
我觉得我在这里错过了一些超级基本的东西。
基本上,要读取文件(尤其是二进制文件),您需要知道文件格式:包括知道一对字节是单个字节的序列,还是单个双字节字。
你没有错过任何东西。定义良好的二进制文件格式(例如 Excel 97-2003 xls 工作簿)必须将字节序作为规范的一部分,否则您显然会遇到大问题。
从历史上看,Macintosh 使用的是大端的摩托罗拉处理器(68000 及其后续产品),而 IBM PC / DOS / Windows 计算机一直使用小端的英特尔处理器。因此,在两个平台上都运行 C/C++ 代码库的软件供应商对这个问题非常熟悉,而在苹果转向英特尔之前一直开发 Windows 软件或 Mac 软件的软件供应商可能只是忽略了它——至少对于他们的自己的文件格式。
不确定这是否正是您要问的,但是,例如,PCAP 文件格式指定了一个变量字节序:
http://www.winpcap.org/ntar/draft/PCAP-DumpFileFormat.html
这个概念是您可以将“标记”字节(例如 0x12345678)写入文件的标题。在诸如 PowerPC 之类的“大端”机器上,它将编写如下:
0x12 0x34 0x56 0x78
在诸如 x86 之类的“小端”机器上,它将编写如下:
0x78 0x56 0x34 0x12
然后,在读取标题时,您可以通过机器读取的内容来判断是否需要在读取文件时交换字节。或者您可以指定一个字节序,例如大字节序。然后你总是会在一个小端机器上交换字节。
对于 PCAP 格式,这样做是出于性能原因。但是指定字节顺序并坚持下去可能更简单。
处理器以一种或另一种字节序模式运行(有些可以根据页面切换等)。他们不知道自己做的是否正确。他们只是做他们该做的。(垃圾进垃圾出) :-)