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

时间:2009-03-23 23:44:48

标签: c# .net encoding stream

我的学习指南(70-536考试)在文章和编码章节中说了两次,就在IO章之后。

到目前为止,所有示例都与使用FileStream和StreamWriter的简单文件访问有关。

它也说“如果您不知道创建文件时要使用的编码,请不要指定一个,.NET将使用UTF16”和“使用Stream构造函数重载指定不同的编码”。

别介意实际的重载在StreamWriter类上,但是嘿,无论如何。

我现在正在反射器中查看StreamWriter,我确信我可以看到默认设置为UTF8NoBOM。

但这些都没有在勘误表中列出。这是一本旧书(对两个版本的错误进行了调整)所以如果它错了,我会认为有人已经接受了......

让我想起也许我不明白。

那么.....任何想法在说什么?还有其他一些违约的地方?

这让我很困惑。

5 个答案:

答案 0 :(得分:37)

“UTF-16”是一个烦人的术语,因为它有两个容易混淆的含义。

第一个含义是一系列16位代码点。其中大多数直接对应于相同数字的Unicode字符;基本多语言平面之外的字符(U + 10000以上)存储为两个16位代码点,每个代码点都是Surrogates

许多语言在这种意义上使用UTF-16进行内部存储,包括作为本机字符串类型。这是“.NET(或Java)使用UTF-16作为其默认编码”这类短语的常见来源。 .NET一次访问这种UTF-16字符串16位的元素(即,在实现级别,作为uint16)。

接下来要考虑的是将这样的UTF-16字符串编码为线性字节,以便存储在文件或网络流中。与往常一样,当您将更大的数字存储为字节时,有两种可能的编码:little-endian或big-endian。所以你可以使用“UTF-16LE”,UTF-16的little-endian编码为字节,或者“UTF-16BE”,即big-endian编码。

(“UTF-16LE”是更常用的。只是为了给火焰添加更多的混淆,Windows给它带来了极其误导和模糊的编码名称“Unicode”。实际上,使用UTF-8几乎总是更好用于文件存储和网络流,而不是UTF-16LE / BE。)

但是如果你不知道一堆字节是否包含“UTF-16LE”或“UTF-16BE”,你可以使用查看第一个代码点的技巧来解决它。此代码点(字节顺序标记(BOM))仅在单向读取时有效,因此您不能将一种编码误认为另一种。

这种方法,不关心你有什么字节顺序,而是用BOM来表示它,通常在编码名称下引用......“UTF-16”。

因此,当有人说“UTF-16”时,你无法判断它们是指一系列短的Unicode Unicode代码点,还是一个未指定顺序的字节序列,它将解码为一个。

(“UTF-32”也有同样的问题。)

  

如果您不知道创建文件时要使用的编码,请不要指定一个,.NET将使用UTF16

如果这是实际的直接引用,那就是谎言。构造一个没有编码参数is explicitly specified的StreamWriter,为您提供UTF-8。

答案 1 :(得分:15)

答案 2 :(得分:3)

测试一下。将字符串“abcd”写入文件。如果它使用UTF8,则文件大小为4个字节。在UTF16下,它将是8个字节。 (加上或许BOM)

答案 3 :(得分:2)

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

答案 4 :(得分:2)

我在静态System.IO.File类中遇到了这个问题。

我想写一个包含UTF-16 XML to file的字符串。

首先,我使用了

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));