字节序理论和概念

时间:2009-01-27 19:06:35

标签: endianness

这不是任何编程语言特有的问题。假设你有一些在big-endian机器上写的文件,你知道这一点。如果两个单字节值背靠背写,你怎么知道? Big-endian会反转16位,32位和64位的顺序,所以您如何知道需要将其作为单个字节读取?

例如,您写入字节0x11,然后写入字节0x22。然后该文件包含0x1122。如果你在一台小端机器上看到它,你必须转换它。所以你会把它读成2211还是1122?你知道吗?

这有什么意义吗?我觉得我在这里缺少一些超级基本的东西。

8 个答案:

答案 0 :(得分:6)

没有办法知道。这就是为什么正式指定的文件格式通常要求字节序,或者它们提供一个选项(如unicode,如MSN所提到的)。这样,如果您正在阅读具有特定格式的文件,则知道它已经是big-endian,因为它采用该格式的事实意味着特定的字节序。

另一个很好的例子是network byte order - 网络协议通常是大端的,所以如果你是一个小端处理器与互联网交谈,你必须向后写东西。如果你是big-endian,你不需要担心它。人们使用htonl and ntohl之类的函数来预处理他们写入网络的内容,以便他们的源代码在所有机器上都是相同的。这些函数被定义为在big-endian机器上什么都不做,但它们在little-endian机器上翻转字节。

关键实现是字节顺序是特定架构表示单词的属性。他们不得不以某种方式编写文件;它只是告诉你,架构上的指令要求多字节字以某种方式对它们的字节进行排序。 big-endian机器可以编写与little-endian机器相同的字节序列,它可能会使用更多指令来执行它,因为它必须重新排序字节。对于编写大端格式的小端机器也是如此。

答案 1 :(得分:2)

你需要对它进行神圣处理,因为你知道别的东西(即你知道你正在读大端格式的文件)或者你需要以某种方式在文件中编码字节序。 Unicode文本文件使用0xFFFE(或类似的东西)作为文本文件的前两个字节来计算字节序。如果你把它读作0xfffe,那么它是原生的endian格式。如果你把它读成0xfeff,那就不是。

答案 2 :(得分:1)

你是完全正确的...如果你对所看到的数据一无所知,就没有办法知道。

话虽如此,通常有猜测的方法......如果你知道你应该看到文字,你可以进行一些简单的测试,看看你得到的是否合理......如果你能读出一个标题,你通常可以从中得到它...但如果你只是看一个字节流,那么知道就没有万无一失的方法了。

答案 3 :(得分:1)

  

这有意义吗?

是的:这是一个问题。

  

我觉得我在这里缺少一些超级基本的东西。

基本上,要读取文件(尤其是二进制文件),您需要知道文件格式:包括知道一对字节是单个字节的序列,还是单个双字节字。

答案 4 :(得分:1)

你没有遗漏任何东西。定义良好的二进制文件格式(例如Excel 97-2003 xls工作簿)必须包含endianness作为规范的一部分,否则您显然会遇到大问题。

从历史上看,Macintosh使用摩托罗拉处理器(68000及其后继产品)是大端的,而IBM PC / DOS / Windows计算机一直使用英特尔处理器,这些处理器都是小端的。因此,在这两个平台上运行的具有C / C ++代码库的软件供应商非常熟悉这个问题,而在苹果公司切换到英特尔之前一直开发Windows软件或Mac软件的软件厂商可能只是忽略了它 - 至少对于他们来说自己的文件格式。

答案 5 :(得分:1)

不确定这是否正是您所要求的,但是,例如,PCAP文件格式指定了变量字节序:

http://www.winpcap.org/ntar/draft/PCAP-DumpFileFormat.html

概念是您可以将“标记”字节(例如0x12345678)写入文件的标题。在诸如PowerPC之类的“大端”机器上,它将写成如下:

0x12 0x34 0x56 0x78

在像x86这样的“小端”机器上,它将写成如下:

0x78 0x56 0x34 0x12

然后,在读取标题时,您可以通过您的机器读出来确定是否需要在读取文件时交换字节。或者您可以指定一个字节序,例如big endian。然后你总是在一个小端机器上交换字节。

对于PCAP格式,这是出于性能原因而完成的。但是指定和结束并且坚持它可能更简单。

答案 6 :(得分:0)

处理器以一种或另一种端模式运行(有些可以根据页面等进行切换)。如果他们做的是正确的话,他们不会知道。他们只是做他们做的事情。 (垃圾进,垃圾出): - )

答案 7 :(得分:0)

没有办法发现我会说。但在C#中,BitConverter具有IsLittleEndian属性。

这完全取决于你想如何输入它。

了解更多here