“UTF-16”是一个令人讨厌的术语,因为它有两个含义容易混淆。
第一个意思是一系列16位代码点。其中大多数直接对应于相同编号的Unicode字符; 基本多语言平面(U + 10000以上)之外的字符存储为两个16位代码点,每个代码点都是
Surrogates之一。
许多语言在这个意义上使用UTF-16进行内部存储,包括作为本地字符串类型。这是常见短语的来源,例如“.NET(或Java)使用UTF-16作为其默认编码”。 .NET以16位的方式(即,在实现级别上,作为uint16)访问此类UTF-16字符串的元素。
接下来要考虑的是将这样的UTF-16字符串编码为线性字节,以便存储在文件或网络流中。当您将较大的数字存储为字节时,总会有两种可能的编码方式:小端或大端。因此,可以使用“UTF-16LE”,即UTF-16转换为字节的小端编码,或“UTF-16BE”,即大端编码。
(“UTF-16LE”是更常用的。为了给混乱增加更多的困惑,Windows给它一个非常误导和模棱两可的编码名称“Unicode”。实际上,与UTF-16LE / BE相比,几乎总是更好地使用UTF-8进行文件存储和网络流。)
但如果你不知道一堆字节是包含“UTF-16LE”还是“UTF-16BE”,你可以使用一个技巧来查看第一个码点以解决它。这个码点,字节顺序标记(BOM),只有在一个方向读取时才有效,因此您不能将一种编码误认为另一种。
这种方法不关心你有什么字节顺序,而是使用BOM来指示它,通常称为编码名称...“UTF-16”。
因此,当有人说“UTF-16”时,您无法确定他们是否意味着短整数Unicode代码点序列,还是一个按未指定顺序解码为其中一种的字节序列。
(“UTF-32”也有同样的问题。)
如果您不知道在创建文件时要使用哪种编码,请不指定任何编码,.NET 将使用 UTF16。
如果这是实际的直接引用,那就是谎言。构造没有编码参数的 StreamWriter
明确指定 会给您UTF-8。