这个问题与this one高度相关,但我会以一种截然不同的方式制定它,因为我无法编辑上面提到的那个。
有一种声称,BOM在UTF-8编码的字符串中是冗余的,因为UTF-8是“面向字节的”,其中最小的代码单元是一个字节,你总是可以从最重要的字符串告诉字节的位是单独表示字符还是仅表示字符表示的一部分。 The Google JavaScript style guide要求在没有BOM的情况下以UTF-8编码保存文件,Jukka Korpela的“Unicode Explained”也指出:
在UTF-8中,没有字节顺序问题,因为代码单元大小是一个八位字节。因此,使用BOM没有任何意义。
假设有一个仅由ASCII字符组成的UTF-8字符串,假设“ abcdefgh ”。如果我将它存储在具有另一个字节序(使用32位字)的机器上,则不会将其更改为“ dcbahgfe ”,因为这里的一个字符是一个字节,它们的顺序是在具有相反字节序的机器上反转(以相反的顺序存储)?
如果不是这种情况,并且字节顺序在内存中始终相同,并且仅在单词中有所不同(在处理类型中),那么为什么字节顺序对于UTF-16编码很重要?即如果我知道,编码是UTF-16而我是地址字节15,我会知道它是字符串中第8个代码单元的第一个字节,我需要得到第二个字节才能找到字符或此代码单元代表的代理对的一部分。
所以有人能告诉我哪里错了吗?我很确定,我对字节序和/或计算机硬件有一些误解,所以如果有人解释这个或给出了更多信息的链接,我将非常感激。
更新:
所以,如果有一个UTF-16字符串,让我们说 abcdefgh 它可以以某种方式存储在内存中 a0b0c0d0e0f0g0h0 或 0a0b0c0d0e0f0g0h (与每两个字节交换,这是我不明白的方式,为什么两个而不是四个)。如果一个人在具有相反字节序的机器上读取此字符串,一次只有一个字节,他仍然需要交换字节。
现在,如果存在相同的UTF-8字符串 abcdefgh ,它将以某种方式存储为字节序列。问题是为什么在这种情况下不交换字节?或者,如果他们这样做,为什么在他阅读时不需要交换它们?因为,据我所知,对于这个级别的硬件和软件,编码之间没有区别,这只是一个字节序列。那么 UTF-16中的字节如何交换,UTF-8中的字节不是?
我故意使用 abcdefg ,以表明即使有这些简单的字符,也可能存在(它不是真的,我知道我错了,但我无法理解为什么) ,需要一个字节进行编码。 AFAIK,在UTF-8中,总能告诉a,b,c等来自寻找字节中最重要位的其他字符。即如果他正在寻址字节13(从1开始)并且 01100001 那么肯定是 a 字符。目前还不知道在这个字符串之前有多少个字符,但事实上这是 a 而不是其他字符编码的一部分很清楚。现在假设我一次读取4个字节,它们的值是a,b,c,d。我如何知道预定的订单?
答案 0 :(得分:4)
你必须意识到处理UTF-8或UTF-16 的机器的字节顺序无关紧要来回答为什么UTF没有字节顺序问题的问题8。重要的是UTF-8和UTF-16是字节流。 UTF-8基于8位代码单元,因此只有一种格式化字节流的方法:简单地将一个字节放在另一个字节之后。另一方面,UTF-16基于16位代码单元。有两种方法可以对字节流中的16位值进行编码:最重要的字节优先(大端)或最低有效字节优先(小端)。这就是为什么有两种UTF-16字节流,通常称为UTF-16-BE和UTF-16-LE。
处理UTF-8时,实际计算机如何寻址,读取和写入内存是一个完全不相关的问题。计算机可能会使用奇怪的寻址方案,这会使UTF-8处理变得复杂,需要字节交换等等。因此可能存在与特定体系结构相关的字节顺序问题,但这些不是关于UTF-8规范的字节顺序问题。实现可以确保只有一种方式是如何格式化UTF-8字节流。
答案 1 :(得分:2)
32位字 - > “dcbahgfe”:您可以通过这种方式查看它,但大多数处理器可以以八位字节访问内存(术语是:内存是字节可寻址的)。因此,如果您的打包数据结构是一个字节序列,它们将具有顺序地址。
如果您读取和写入单词并将其视为较大的整数,则必须按特定顺序打包字节,但这不是字节顺序问题,而是该级别的算术字。
就协调而言,它取决于编译器和堆库。许多将在结构之间填充,以便每个结构都在有效的地址边界上开始。