UTF-8或UTF-16或UTF-32或UCS-2

时间:2010-08-13 01:37:46

标签: c# asp.net unicode

我正在设计一个新的CMS,但我想设计它以满足我未来的所有需求,如多语言内容,所以我认为Unicode(UTF-8)是最好的解决方案

但是通过一些搜索,我得到了这篇文章

http://msdn.microsoft.com/en-us/library/bb330962%28SQL.90%29.aspx#intlftrql2005_topic2

所以我现在很困惑现在使用什么 UTF-8 / UTF-16 / UTF-32 / UCS-2

这对于多语言内容和性能等更好。

PS:我使用的是Asp.net和c#以及SqlServer 2005

提前致谢

6 个答案:

答案 0 :(得分:25)

  

所以我现在很困惑现在要用什么   UTF-8 / UTF-16 / UTF-32 / UCS-2

     

这对多语言更好   内容和表现等。

UCS-2已过时:它不再代表每个Unicode字符。 UTF-8,UTF-16和UTF-32都可以。但为什么有三种不同的方法来编码相同的字符?

因为在过去,程序员对字符串做了两个很大的假设。

  1. 该字符串由8位代码单元组成。
  2. 那1个字符= 1个代码单元。
  3. 多语言文本(或者甚至是单语文本,如果该语言恰好是中文,日文或韩文)的问题在于这两个假设的组合限制为256个字符。如果你需要代表更多,你需要放弃其中一个假设。

    保持假设#1并丢弃假设#2会为您提供可变宽度(或多字节编码。今天,最流行的可变宽度编码是UTF-8。

    删除假设#1并保持假设#2为您提供宽字符编码。 Unicode和UCS-2最初设计为使用16位固定宽度编码,允许65,536个字符。 Unicode的早期采用者,例如Sun(用于Java)和Microsoft(用于NT)使用UCS-2。

    然而,几年后,人们意识到即使 对每个人都不够,所以扩展了Unicode代码范围。现在,如果你想要一个固定宽度的编码,你必须使用UTF-32。

    但Sun和微软已经编写了大量基于16位字符的API,并且并不热衷于为32位重写它们。幸运的是,在最初的65,536个字符的“基本多语种平面”中仍然存在2048个未分配字符块,可以将其指定为“代理”以成对使用来表示补充字符:UTF-16编码形式。不幸的是,UTF-16符合原来两个假设的 :它都是非8位和可变宽度。

    总结:

    假设8位代码单位很重要时使用UTF-8。

    这适用于:

    • Unix系统上的文件名和相关的OS调用,它具有允许可变宽度编码的传统,但不能接受字符串中的'\x00字节,因此不能使用UTF-16或UTF-32 。实际上,UTF-8最初是为基于Unix的操作系统<计划9设计的
    • 围绕八位字节流设计的通信协议。
    • 任何需要与US-ASCII二进制兼容的内容,但不对127以上的字节值进行特殊处理。

    假设固定宽度编码很重要时使用UTF-32。

    当你关心字符的属性而不是它们的编码时,这很有用,例如ctypes.h函数的Unicode等价物,如isalpha,{{1 },isdigit

    当两个假设都不重要,但您的平台曾经使用过UCS-2时,请使用UTF-16。

    您是在为Windows编写,还是为其设计的.NET框架?对于Java?那么UTF-16是你的默认字符串类型;不妨用它。

    由于您使用的是C#,因此所有字符串都将以UTF-16编码。 ASP.NET将以UTF-8编码实际的HTML页面,但这是在幕后完成的,您无需关心。

    尺寸注意事项

    三种UTF编码形式需要不同的内存量来表示字符:

    • 字符U + 0000到U + 007F(ASCII)需要UTF-8中的1个字节,UTF-16中的2个字节或UTF-32中的4个字节。
    • 字符U + 0080到U + 07FF(IPA符号,希腊语,西里尔语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语,Thaana语,NKo语言)需要UTF-8中的2个字节,UTF-16中的2个字节或4个字节中的UTF-32。
    • 字符U + 0800到U + FFFF(BMP的其余部分,主要用于亚洲语言)需要UTF-8中的3个字节,UTF-16中的2个字节或UTF-32中的4个字节。
    • 字符U + 10000到U + 10FFFF在所有三种编码形式中都需要4个字节。

    因此,如果你想节省空间,如果你的角色大多是ASCII,则使用UTF-8;如果你的角色主要是亚洲人,则使用UTF-16。

答案 1 :(得分:13)

这不是问题,因为你说:

  

我使用的是Asp.net和c#以及SqlServer 2005

SqlServer在一些以XML为中心的地方使用UTF-16(ntext,nvarchar,nchar)和UTF-8,而不会做任何奇怪的事情。

C#在其所有字符串中使用UTF-16,在处理将我们带入的流和文件时使用工具进行编码...

ASP.NET默认使用UTF-8,很难想象它不是一个好的选择(即使使用亚洲语言,这些语言的文本简洁结合了名称和符号这一事实具有特殊含义的HTML,CSS,javascript,大多数XML应用程序以及你将要发送的其他流都是从U + 0000到U + 007F的范围,UTF-16优于UTF-8的优势在此范围内不如亚洲语言的纯文本。)

SqlServer的UTF-16和C#以及ASP.NET在读写时所做的UTF-8之间的谈话是使用默认设置为您完成的,但由于这是您可以随时更改的一位,因此我的答案是使用UTF-8。你真的会使用-8和-16的混合物,但大多数时候你都不会注意到(你注意到你已经这样做了)。

SQL Server有点不太宽容,只是因为很多过时的例子都有人类消费的文本放在varchar,text或char字段中。纯粹用于代码(例如,所有ISO国家代码都在char(2)范围内,因此nchar(2)只会浪费空间),只有nvarchar,ntext和nchar用于人们而不是机器的东西才能读写。

答案 2 :(得分:3)

首先,忘掉UCS-2:它已经过时了。它仅包含Unicode字符的子集。忘记UTF-32:它非常庞大且非常冗余。它对数据传输没有用。

在网页中,如果你处理的大部分语言都是西式语言(拉丁语,西里尔语,希腊语等),那么最经济的就是UTF-8。但如果带宽和加载时间不是问题,那么你也可以使用UTF-16。只需确保在处理byte[]时始终知道数据的格式。并且不要尝试转换为过时的8位字符集,例如ISO-8859或Windows-1252,因为如果你这样做会丢失数据。

在C#代码中,您的string对象将在内部使用UTF-16,并且您无法做任何事情。因此,您的正常字符串操作(例如Substring())不受您选择的输出格式的影响。有人可能会说,这使得编码为UTF-16的性能更高,但如果你要通过互联网传输它,那就不值得了,因为传输更大的UTF-16的成本超过了微小的处理收益。 / p>

在SQL Server中,您应该使用nvarchar(...)

答案 3 :(得分:2)

UTF-8或UTF-16都是不错的选择。它们都允许您访问所有Unicode代码点,而不会为每个字符使用4个字节。

您的选择将受到您使用的语言及其对这些格式的支持的影响。我相信 UTF-8 在整体上与ASP.NET相得益彰,但这取决于你正在做什么。

UTF-8通常是一个很好的选择,因为它可以很好地使用只需要ASCII的代码,而UTF-16则不然。它也是表示主要由我们的英文字母组成的内容的最有效方式,同时在需要时仍然允许完整的Unicode库。选择UTF-16的一个很好的理由是,如果您的语言/框架本身使用它,或者您将主要使用不是ASCII的字符,例如亚洲语言。

答案 4 :(得分:1)

快速注意:基本上所有内容都可以用unicode 字符集表示。 UTF-8只是一个编码,能够代表该集合中的所有字符。

UCS-2不再是一个可以使用的东西了。它不能保存超出U + FFFF的字符。

其余三个中的哪一个取决于您要对文本执行何种操作。 UTF-8(通常,并非总是如此!)将占用代表相同数据的磁盘上较少的空间,并且是ASCII的严格超集,因此它可能会减少所需的转码量。但是,您无法索引字符串或在常量时间内查找其长度。

UTF-32允许您查找字符串的长度并在恒定时间内对其进行索引。它不像UTF-8那样是ASCII的超集。它还要求每个代码点有4个字节,但是,磁盘空间很便宜。

答案 5 :(得分:1)

唉我认为问题是(正如他在开头所说)他有SQL Server 2005,如果我是正确的仍然使用UCS2,因为它编码N数据类型(NVARCHAR和co)

他可能不得不忍受带来或升级到更新版本的SQL Server的限制。通常情况下,如果您开始转储UTF-16,即.NET中使用的标准unicode,您将看到的是,如上所述,某些字符将丢失并替换为?数据库表中的标记。