UTF-16是一种双字节字符编码。交换两个字节'地址将产生UTF-16BE和UTF-16LE。
但我发现Ubuntu gedit
文本编辑器中存在名称UTF-16编码,以及UTF-16BE和UTF-16LE。使用C测试程序,我发现我的计算机是小端,UTF-16被确认为UTF-16LE的相同编码。
另外:在小/大端计算机中有两个字节顺序的值(例如整数)。小端计算机将在硬件中产生很少的字节序值(除了Java生成的值,它总是形成一个大端)。
虽然文本可以在我的小端计算机中保存为UTF-16LE和UTF-16BE,但是字符是一个字节一个字节生成的(例如ASCII字符串,参考[3]和UTF的字节顺序 - 16只是由人类定义 - 不是因为大端机器写大端UTF-16而小端机器写小端UTF-16的现象?
答案 0 :(得分:5)
“UTF-16的结尾是计算机的字节序吗?”
可以从文件的 writer 或 reader 的角度来看待计算机字节序的影响。
如果您正在以标准格式阅读文件,那么阅读它的机器应该无关紧要。格式应该足够明确,无论读取机器的字节顺序是什么,数据仍然可以正确读取。
这并不意味着格式不灵活。使用“UTF-16”(当格式名称中未使用“BE”或“LE”歧义消除时),该定义允许将文件标记为 大端或小端。这是通过文件的前两个字节中的“字节顺序标记”(BOM)来完成的:
https://en.wikipedia.org/wiki/Byte_order_mark
BOM的存在为文件的编写者提供了选项。他们可能会选择为内存中的缓冲区写出最自然的字节序,并包含匹配的BOM。对于其他读者来说,这不一定是最有效的格式。但任何声称支持UTF-16的程序都应该能够处理它。
是的 - 计算机的字节序可能会影响BOM标记的UTF-16文件的字节序选择。仍然...一个小端程序完全能够保存文件,标记为“UTF-16”并让它成为大端。只要BOM与数据一致,无论哪种机器写入或读取它都无关紧要。
...如果没有BOM会怎样?
这是事情变得有点朦胧的地方。
一方面,Unicode RFC 2781和Unicode FAQ很清楚。他们说,“UTF-16”格式的文件既不是0xFF 0xFE
也不是0xFE 0xFF
,而是interpreted as big endian:
默认情况下,未标记的表单使用大端字节序列化,但可能在开头包含一个字节顺序标记,以指示使用的实际字节序列化。
但是要知道你是否有没有BOM的UTF-16-LE,UTF-16-BE或UTF-16文件...你需要文件外的元数据告诉你它们中的哪一个。因为并不总是放置数据的地方,所以一些程序使用启发式算法。
考虑类似this from Raymond Chen (2007)的内容:
您可能认为生成没有BOM的UTF-16文件的程序已损坏,但这并不意味着它们不存在。例如,
cmd /u /c dir >results.txt
这会生成一个没有BOM的UTF-16LE文件。
这是一个有效的UTF-16LE文件,但存储“UTF-16LE”元标签的位置在哪里?有人通过称之为UTF-16文件来传递这种情况的几率是多少?
根据经验,该术语有警告。维基百科page for UTF-16说:
如果BOM丢失,RFC 2781表示应该假设大端编码。 (实际上,由于Windows默认情况下使用little-endian顺序,许多应用程序默认情况下会假设使用little-endian编码。)
“UTF-16”和“UTF-32”编码名称不精确:根据上下文,格式或协议,它表示带有BOM标记的UTF-16和UTF-32,或UTF-16和UTF-32没有BOM的主机端。在Windows上,“UTF-16”通常表示UTF-16-LE。
此外,Byte-Order-Mark Wikipedia article说:
Unicode标准的条款D98(第3.10节)规定,“UTF-16编码方案可能会也可能不会以BOM开头。但是,如果没有BOM,并且没有更高级别的BOM协议,UTF-16编码方案的字节顺序是big-endian。“
更高级别的协议是否有效可以解释。例如,本机字节排序为little-endian的计算机本地文件可能被认为是隐式编码为UTF-16LE。因此,大端的推定被广泛忽视。
当互联网上可以访问这些相同的文件时,另一方面 手,没有这样的推定。搜索16位字符 在ASCII范围内或只是空格字符(U + 0020)是一种方法 确定UTF-16字节顺序。
因此,尽管标准没有歧义,但背景在实践中可能很重要。
正如@rici指出的那样,该标准现在已经存在了一段时间。不过,对声称为“UTF-16”的文件进行双重检查可能需要付费。或者甚至考虑你是否想要避免很多这些问题并接受UTF-8 ......
答案 1 :(得分:1)
没有。你不是看到小端计算机一直接收来自互联网的数据包,这是大端吗?
编码取决于您对内存的写入方式,而不是您的架构的编写方式。
答案 2 :(得分:1)
Unicode编码方案在Unicode standard的第3.10节中定义。该标准定义了七种编码方案:
对于16位和32位编码,这三种变体的字节顺序不同,可以是显式的,也可以通过以Byte Order Mark(BOM)字符开头的字符来表示,U + FEFF:< / p>
LE
变体绝对是小端的;首先编码低位字节。不允许BOM,因此初始字符U + FEFF是零宽度不间断空间。 BE
变种绝对是大端的;首先编码高位字节。与LE
变体一样,不允许使用BOM,因此初始字符U + FEFF是零宽度不间断空间。如果要使用16位或32位编码方案进行数据序列化,通常建议使用带有显式BOM的未标记变体。但是,UTF-8是一种更常见的数据交换格式。
虽然UTF-8不需要字节序标记,但允许(但不推荐)使用BOM启动UTF-8编码字符串;这可以用于区分Unicode编码方案。许多Windows程序都这样做,并且在UTF-8传输开始时的U + FEFF应该被视为BOM(因此不是Unicode数据)。