关于C#:为什么.NET对字符串使用UTF16编码,但对保存文件使用UTF8作为默认编码?

Why does .net uses the UTF16 encoding for string , but uses utf8 as default for saving files?

从这里

Essentially, string uses the UTF-16 character encoding form

但是当保存vs streamwriter时:

This constructor creates a StreamWriter with UTF-8 encoding without a
Byte-Order Mark (BOM),

我看到这个示例(断开的链接被删除):

enter image description here

有些字符串的utf8较小,有些字符串的utf-16较小。

  • 那么为什么.NET使用utf16作为字符串的默认编码,而utf8用于保存文件?

谢谢您。

我已经读过那篇著名的文章了


如果你很乐意忽略代理对(或者相当于,你的应用程序可能需要基本多语言平面以外的字符),utf-16有一些很好的属性,基本上是因为每个代码单元都需要两个字节,并且在一个代码单元中表示所有BMP字符。

考虑原始类型char。如果我们使用UTF-8作为内存中的表示,并且希望处理所有Unicode字符,那么它应该有多大?最多可以有4个字节…这意味着我们必须分配4个字节。在这一点上,我们最好使用UTF-32!

当然,我们可以使用utf-32作为char表示,但是在string表示中使用utf-8,并按我们的方式转换。

UTF-16的两个缺点是:

  • 每个Unicode字符的代码单位数是可变的,因为并非所有字符都在BMP中。直到emoji变得流行,这并没有影响很多日常使用的应用程序。现在,当然对于消息应用程序等,使用UTF-16的开发人员确实需要了解代理对。
  • 对于纯ASCII(很多文本,至少在西方是这样),它需要相当于UTF-8编码文本两倍的空间。

(顺便说一句,我相信Windows对Unicode数据使用UTF-16,而且.NET也有必要根据互操作的原因采用这种方法。但这只会把问题推到一步。)

考虑到代理对的问题,我怀疑如果一种语言/平台是从零开始设计的,没有互操作要求(但是基于Unicode的文本处理),那么UTF-16将不是最佳选择。无论是UTF-8(如果你想提高内存效率,并且不介意处理复杂度达到第n个字符),还是UTF-32(反过来说)都是一个更好的选择。(甚至进入第n个字符也有"问题",这是因为不同的规范化形式。文本很难…)


正如许多"为什么选择"的问题一样,这是由历史决定的。Windows在1993年成为其核心的Unicode操作系统。当时,Unicode仍然只有65535个码位,这些日子被称为ucs。直到1996年,Unicode才获得了将编码空间扩展到一百万个码位的补充平面。以及代理对,以使它们适合于16位编码,从而设置UTF-16标准。

.NET字符串是UTF-16,因为它非常适合操作系统编码,不需要转换。

UTF-8的历史更为模糊。绝对超过Windows NT,RFC-3629的日期是1993年11月。花了一段时间才站稳脚跟,互联网就是工具。


UTF-8是文本存储和传输的默认格式,因为它对大多数语言都是相对紧凑的格式(有些语言在UTF-16中比在UTF-8中更紧凑)。每种特定的语言都有一种更有效的编码。

UTF-16用于内存中的字符串,因为每个字符解析和直接映射到Unicode字符类和其他表的速度更快。Windows中的所有字符串函数都使用UTF-16,并且使用了多年。