有没有理由比UTF-8更喜欢UTF-16?

检查UTF-16和UTF-8的属性,我找不到任何理由更喜欢UTF-16。

但是,检查Java和C#,它看起来像字符串和字符默认为UTF-16。 我认为这可能是出于历史原因,或者出于性能原因,但无法找到任何信息。

有谁知道为什么这些语言选择UTF-16? 还有什么理由让我这样做吗?

编辑:同时我也找到了这个答案 ,这似乎是相关的,并有一些有趣的链接。

与UTF-8(通常需要3个字节)相比,东亚语言通常需要较少的UTF-16存储空间(2个字节足以满足99%的东亚语言字符)。

当然,对于西方联盟,UTF-8通常较小(1字节而不是2字节)。 对于像HTML这样的混合文件(其中有很多标记),它非常多。

为用户模式应用程序处理UTF-16比处理UTF-8 稍微容易一些,因为代理对的行为几乎与组合字符的行为相同。 因此,UTF-16通常可以作为固定大小的编码处理。

@Oak:这个评论太长了……

我不知道C#(并且会非常惊讶:这意味着他们只是过多地复制了Java)但是对于Java来说它很简单:Java是在Unicode 3.1出现之前构思出来的。

因此,少于65537个代码点,因此每个Unicode代码点仍然适合16位,因此Java char诞生了。

当然,这导致了疯狂的问题仍然影响着今天的Java程序员(比如我),你有一个方法charAt在某些情况下确实既不返回Unicode字符也不返回Unicode代码点和方法(在Java 5中添加) codePointAt获取一个参数,该参数不是您想要跳过的代码点数量! (您必须向codePointAt提供要跳过的Java char的数量,这使它成为String类中最不易理解的方法之一)。

所以,是的,这绝对是令人困惑的大多数Java程序员(大多数甚至都不知道这些问题),并且,是的,这是出于历史原因。 至少,这是人们在这个问题之后生气的原因但是因为Unicode 3.1还没有出来

🙂

我想使用UTF-16的C#派生自内部使用UTF-16的Windows NT系列操作系统。

我想Windows NT在内部使用UTF-16有两个主要原因:

  • 对于内存使用:UTF-32浪费了大量空间进行编码。
  • 性能方面:UTF-8比UTF-16更难解码。 在UTF-16中,字符是基本多语言平面字符(2个字节)或代理项对(4个字节)。 UTF-8字符可以是1到4个字节之间的任何位置。

与其他人的答案相反 – 你不能将UTF-16视为UCS-2 。 如果要正确迭代字符串中的实际字符,则必须使用对unicode友好的迭代函数。 例如,在C#中,您需要使用StringInfo.GetTextElementEnumerator()

有关详细信息,请参阅维基上的此页面: http : //en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

这取决于预期的字符集。 如果您期望在7位ASCII范围之外大量使用Unicode代码点,那么您可能会发现UTF-16将比UTF-8更紧凑,因为一些UTF-8序列长度超过两个字节。

此外,出于效率原因,Java和C#在索引字符串时不考虑代理对。 当使用以UTF-8序列表示占用奇数个字节的代码点时,这将完全分解。

UTF-16可以更有效地表示某些语言中的字符,例如中文,日文和韩文,其中大多数字符可以用一个16位字表示。 一些很少使用的字符可能需要两个16位字。 UTF-8通常更有效地表示来自西欧字符集的字符 – UTF-8和ASCII在ASCII范围(0-127)上是等效的 – 但对亚洲语言效率较低,需要三或四个字节来表示字符可以用UTF-16中的两个字节表示。

UTF-16作为Java / C#的内存格式具有优势,因为基本多语言平面中的每个字符都可以用16位表示(参见Joe的答案)和UTF-16的一些缺点(例如,令人困惑的代码依赖on \ 0终止符)不太相关。

对于许多(大多数?)应用程序,您将只处理Basic Multilingual Plane中的字符,因此可以将UTF-16视为固定长度编码。

因此,您可以避免使用UTF-8等可变长度编码的所有复杂性。