c# - "The .NET framework uses the UTF-16 encoding standard by default"是什么意思?

标签 c# .net encoding stream

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

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

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

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

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

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

让我觉得我可能没听懂。

所以.....知道它在说什么吗?其他有默认值的地方?

这让我很困惑。

最佳答案

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

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

许多语言在这种意义上使用 UTF-16 进行内部存储,包括作为 native 字符串类型。这是“.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”时,您无法判断它们是指一系列 short-int Unicode 代码点,还是指将解码为一个的未指定顺序的字节序列。

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

If you don't know what encoding to use when you create a file, don't specify one and .NET will use UTF16

如果那是实际的直接引述,那就是谎言。构建不带编码参数的 StreamWriter is explicitly specified给你 UTF-8。

关于c# - "The .NET framework uses the UTF-16 encoding standard by default"是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/675651/

相关文章:

c# - 优化 : How should i Optimize the Linq Concat of Collections? C#

c# - 在哪里以及如何使用嵌套类?

C# - 帮助自定义 DatagridView 单元格选项

javascript - 鼠标悬停在图像上时按钮隐藏

.net - Bug Tracker .NET - 如何仅从数据库确定版本?

ruby-on-rails - Ruby on Rails、ActiveRecord、Postgres、UTF-8 和 ASCII-8BIT 编码

python - 处理包含多个字符编码的字符串

c# - 使用静态类作为另一个类的输入参数

c# - 从 raven db 文档存储加载对象时如何防止属性被序列化

python - 如何在 C 中将字符串编码更改为 utf 8