我从来没有理解过UTF-16编码的要点。如果您需要能够将字符串视为随机访问(即代码点与代码单元相同),那么您需要UTF-32,因为UTF-16仍然是可变长度的。如果您不需要这个,那么与UTF-8相比,UTF-16似乎是一个巨大的空间浪费。与UTF-8和UTF-32相比,UTF-16有什么优势?为什么Windows和Java使用UTF-16作为本机编码?
发布于 2011-03-14 04:36:39
在设计Windows NT时,UTF-16还不存在(NT3.51诞生于1993年,而UTF-16诞生于1996年,符合Unicode 2.0标准);取而代之的是UCS-2,在那个时候,它足以容纳Unicode中所有可用的字符,因此1个代码点=1个代码单元的等价性实际上是正确的-字符串不需要可变长度逻辑。
他们后来转到了UTF-16,以支持整个Unicode字符集;但是,他们不能转到UTF-8或UTF-32,因为这会破坏API接口中的二进制兼容性(以及其他)。
至于Java,我不太确定;因为它是在1995年发布的,我怀疑UTF-16已经发布了(即使它还没有标准化),但我认为与基于NT的操作系统的兼容性可能在他们的选择中起到了一定的作用(每次调用Windows API时,连续的UTF-8 <-> UTF-16转换可能会带来一些减慢)。
编辑
维基百科解释说,即使对于Java,它也是以同样的方式进行的:它最初支持UCS-2,但在J2SE 5.0中迁移到UTF-16。
因此,一般来说,当您在一些API/Framework中看到UTF-16时,这是因为它作为UCS-2启动(以避免字符串管理算法中的复杂性),但它迁移到UTF-16以支持BMP之外的代码点,仍然保持相同的代码单元大小。
发布于 2014-01-05 17:11:45
除了向后兼容性回复之外,所有表明UTF-16优于UTF-8的回复都没有任何意义。
好吧,对我的评论有两点警告。
Erik说:"UTF-16用单个单元覆盖了整个BMP --所以除非你需要BMP之外的稀有字符,否则UTF-16实际上是每个字符2个字节。“
注意事项1)
如果您可以确定您的应用程序永远不会需要BMP之外的任何字符,并且您编写的用于BMP之外的任何库代码都不会与需要BMP之外的字符的任何应用程序一起使用,那么您可以使用UTF-16,并编写这样的代码,该代码隐含地假设每个字符的长度都恰好是两个字节。
这看起来非常危险(实际上是愚蠢的)。
如果您的代码假设所有UTF-16字符的长度均为两个字节,并且您的程序与BMP之外只有一个字符的应用程序或库进行交互,则您的代码将中断。必须编写检查或操作UTF-16的代码来处理UTF-16字符需要超过2个字节的情况;因此,我“忽略”这一警告。
UTF-16的编码并不比UTF-8简单(两者的代码都必须处理可变长度的字符)。
注意事项2)
在某些情况下,如果编写得当,UTF-16的计算效率可能会更高。
就像这样:假设某些长字符串很少被修改,但经常被检查(或者更好的是,一旦构建就从来没有修改过--即一个字符串构建器创建不可修改的字符串)。可以为每个字符串设置一个标志,指示该字符串是否只包含“固定长度”字符(即,不包含长度恰好不是两个字节的字符)。可以使用假定固定长度(2字节)字符的优化代码来检查标志为true的字符串。
那么空间效率呢?
显然,对于A)字符,UTF-16比UTF-8编码需要更少的字节,因此UTF-16更有效。
显然,对于B)字符,UTF-8比UTF-16编码需要更少的字节,因此UTF-8更有效。
除了非常“特殊”的文本,count(B)很可能远远超过count(A)。
发布于 2011-03-14 04:32:39
UTF-16使用单个单元覆盖整个BMP -因此,除非您需要BMP之外的稀有字符,否则UTF-16实际上是每个字符2个字节。UTF-32占用更多空间,UTF-8需要可变长度支持。
https://stackoverflow.com/questions/5292150
复制相似问题