".NET框架默认使用UTF-16编码标准"是什么意思?"

17

我的学习指南(针对70-536考试)在IO章节之后的文本和编码章节中两次提到了这一点。

到目前为止,所有的例子都是使用FileStream和StreamWriter进行简单的文件访问。

它还说:“如果您创建文件时不知道要使用哪种编码方式,请不要指定任何编码方式,.NET将使用UTF16”,以及“使用Stream构造函数重载来指定不同的编码方式”。

不要介意实际上重载是在StreamWriter类上,但没关系。

我现在正在Reflector中查看StreamWriter,我确定我可以看到默认值实际上是UTF8NoBOM。

但是没有这些内容列在勘误表中。这是一本旧书(检查了两个版本的勘误表),如果有错误,我认为会有人注意到.....

这让我想到也许我没有理解它。

那么...你们有什么想法?其他地方有默认设置吗?

这让我感到非常困惑。

5个回答

39
“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。

1
+1哇,谢谢你这个很棒的回复。我正在消化中。如果我能投两次赞就好了 :)。 - J M


3

测试一下。将字符串"abcd"写入文件中。如果使用UTF8编码,文件大小为4字节。在UTF16编码下,文件大小为8字节。(可能还有BOM)


我在使用StreamWriter时进行了断点测试并检查了StreamWriter的编码 - 它是UTF8NoBOM。由于所有示例都是这样做的,而且书中没有详细说明,所以我不知道他们在说什么... - J M
你需要指定StreamWriter使用的编码。 - Matthew Olenik

2

我遇到了与静态类 System.IO.File 相关的问题。

我想要将包含UTF-16 XML的字符串写入文件。

首先,我使用了

using(StreamWriter writer = File.CreateText(xmlFilePathTarget))
{
    writer.Write(xmlString);
}

但是由于它将字符串写成UTF-8格式,IE无法打开并显示错误信息:

无法显示XML页面 无法使用样式表查看XML输入。 请更正错误,然后单击“刷新”按钮或稍后再试。


不支持从当前编码转换为指定编码。 处理资源时出错“file:///C:/Documents and Setti...

非常感谢这篇文章,我找到解决方法是明确使用StreamWriter构造函数:
StreamWriter writer = new StreamWriter(xmlFilePathTarget, false, Encoding.Unicode));

2

UTF16是.NET在编码程序中(如字符串变量)使用的默认编码。


是的,但LE或BE也很重要,它是哪个? - phil soady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接