【问题标题】:What does "The .NET framework uses the UTF-16 encoding standard by default" mean?“.NET 框架默认使用 UTF-16 编码标准”是什么意思?
【发布时间】:2010-10-15 02:37:08
【问题描述】:

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

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

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

不要介意实际重载在 StreamWriter 类上的事实,但是,无论如何。

我现在正在反射器中查看 StreamWriter,我确信我可以看到默认值实际上是 UTF8NoBOM。

但勘误表中没有列出这些。这是一本旧书(检查了两个版本的错误)所以如果它是错误的,我会认为有人已经拿起它.....

让我觉得我可能没听懂。

那么......任何想法它在说什么?其他有默认值的地方?

这让我很困惑。

【问题讨论】:

    标签: c# .net encoding stream


    【解决方案1】:

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

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

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

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

    (“UTF-16LE”是更常用的。只是为了火上浇油,Windows 给它起了一个极具误导性和模棱两可的编码名称“Unicode”。实际上,使用 UTF-8 几乎总是更好用于文件存储和网络流,而不是 UTF-16LE/BE。)

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

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

    因此,当有人说“UTF-16”时,您无法判断他们是指短整型 Unicode 代码点序列,还是会解码为 1 的未指定顺序的字节序列。

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

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

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

    【讨论】:

    • +1 哇,感谢您的精彩回复。我正在消化。如果我可以投票两次,我会:)。
    【解决方案2】:
    【解决方案3】:

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

    【讨论】:

    • 我在使用 StreamWriter 时通过断点和检查 StreamWriter 的编码对其进行了测试——它是 UTF8NoBOM。由于所有的例子都是这样完成的,而且书中没有详细说明,所以我没有得到它们的内容......
    • 您需要指定StreamWriter使用的编码。
    【解决方案4】:

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

    【讨论】:

    • 是的,但 LE 或 BE 也很重要,是什么?
    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 2011-12-18
      • 1970-01-01
      • 2018-03-12
      • 2010-12-24
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      相关资源
      最近更新 更多