免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3032 | 回复: 2
打印 上一主题 下一主题

Java中文处理学习笔记——Hello Unicode 【转贴】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-09-25 22:06 |只看该作者 |倒序浏览
http://www.chedong.com/tech/hello_unicode.html
内容摘要:

不知道你有没有这样的感受:为什么PHP很少有乱码问题而用Java做WEB应用却这么麻烦呢?为什么在Google上能用简体中文查到繁体中文,甚至日文的结果?而且用Google的时候发现它居然能自动根据我使用浏览器的语言选择自动调出中文界面?


很多国际化应用的让我理解了这么一个道理:Unicode是为更方便的做国际化应用设计的,而Java核心的字符是基于UNICODE的,这一机制为应用提供了对中文“字”的控制(而不是字节)。但如果不仔细理解其中的规范,这种自由反而会成为累赘,从而导致更多的乱码问题:

关于字符集的一些基本概念;
试验1:显示系统的环境设置和支持的编码方式;
试验2:系统缺省编码方式对Java应用的输入输出影响;
试验3:在WEB应用中输出和输出中的字符集问题;

关于字符集的准备知识:
ISO-8859-1 GB2312 BIG5 GBK GB18030 UNICODE 为什么会有这么多字
符集编码方式?

注意:以下说明不是严格定义,一些比喻仅作为方便理解使用。

假设一个字符就是棋盘上的一个棋子,有其固定的坐标,如果需要区别所有的字符,就需要有足够的棋格容纳不同的“字符”。 

英文和欧洲其他语言的单字节字符集(SingleByte Charsets):
首先对于ISO-8859系列的字符集都想象成一个:2^8 = 16 * 16 = 256个格子的棋盘,这样所有的西文字符(英文)用这样一个16×16的坐标系就基本可以覆盖全了。而英文实际上只用其中小于128(\x80)的部分就够了。利用大于128部分的空间的不同定义规则形成了真对其他欧洲语言的扩展字符集:ISO-8859-2 ISO-8859-4等……

ISO-8859-1
ISO-8859-7
其他语言

英文 其他西欧字符
ōē
……………………………………………………




GB2312 BIG5 SJIS等多字节字符集(MultiByte Charsets):
对于亚洲语言来说:汉字这么多,用这么一个256格的小棋盘肯定放不下,所以要区别成千上万的汉字解决办法就是用2个字节(坐标)来定位一个“字”在棋盘上的位置,将以上规则做一个扩展:

如果第1个字符是小于128(\x80)的仍和英文字符集编码方式保持兼容;
如果第1个字符是大于128(\x80)的,就当成是汉字的第1个字节,这个自己和后面紧跟的1个字节组成一个汉字;
其结果相当于在位于128以上的小棋格里每个小棋格又划分出了一个16×16的小棋盘。这样一个棋盘中的格子数(可能容纳的字符数)就变成了128 + 128 * 256。按照类似的方式有了简体中文的GB2312标准,繁体中文的BIG5字符集和日文的SJIS字符集等,GB2312字符集包含大约有六仟多个常用简体汉字。
………………………………



由此可以看出,所有这些从ASCII扩展式的编码方式中:英文部分都是兼容的,但扩展部分的编码方式是不兼容的,虽然很多字在3种体系中写法一致(比如“中文”这2个字)但在相应字符集中的坐标不一致,所以GB2312编写的页面用BIG5看就变得面目全非了。而且有时候经常在浏览其他非英语国家的页面时(比如包含有德语的人名时)经常出现奇怪的汉字,其实就是扩展位的编码冲突造成的。

我把GBK和GB18030理解成一个小UNICODE:GBK字符集是GB2312的扩展(K),GBK里大约有贰万玖仟多个字符,除了保持和GB2312兼容外,繁体中文字,甚至连日文的假名字符也能显示。而GB18030-2000则是一个更复杂的字符集,采用变长字节的编码方式,能够支持更多的字符。关于汉字的编码方式比较

详细的定义规范可以参考:

http://www.unihan.com.cn/cjk/ana17.htm


ASCII(英文) ==>; 西欧文字 ==>; 东欧字符集(俄文,希腊语等) ==>; 东亚字符集(GB2312 BIG5 SJIS等)==>; 扩展字符集GBK GB18030这个发展过程基本上也反映了字符集标准的发展过程,但这么随着时间的推移,尤其是互联网让跨语言的信息的交互变得越来越多的时候,太多多针对本地语言的编码标准的出现导致一个应用程序的国际化变得成本非常高。尤其是你要编写一个同时包含法文和简体中文的文档,这时候一般都会想到要是用一个通用的字符集能够显示所有语言的所有文字就好了,而且这样做应用也能够比较方便的国际化,为了达到这个目标,即使应用牺牲一些空间和程序效率也是非常值得的。UNICODE就是这样一个通用的解决方案。

UNICODE双字节字符集

所以你可以把UNICODE想象成这样:让所有的字符(包括英文)都用2个字节(2个8位)表示,这样就有了一个2^(8*2) = 256 * 256 = 65536个格子的大棋盘。在这个棋盘中,这样中(简繁)日韩(还包括越南)文字作为CJK字符集都放在一定的区位内,为了减少重复,各种语言中写法一样的字共享一个“棋格”。详细的区位见附录A
………………………………………………………………………………………………………………………………………………………………

详细信息浏览下面的主页

http://www.chedong.com/tech/hello_unicode.html
作者: 车东 Email: chedongATbigfoot.com/chedongATchedong.com
参考文档:
Java的国际化设计
http://java.sun.com/docs/books/tutorial/i18n/index.html

Linux 国际化本地化和中文化
http://www.linuxforum.net/doc/i18n-new.html

Linux 程序员必读:中文化与GB18030标准
http://www.ccidnet.com/tech/os/2001/07/31/58_2811.html

Unicode FAQ
http://www.cl.cam.ac.uk/~mgk25/unicode.html
http://www.linuxforum.net/books/UTF-8-Unicode.html (中文版)

Java 编程技术中汉字问题的分析及解决
http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml

汉字的编码方式:
http://www.unihan.com.cn/cjk/ana17.htm

不同版本的JVM支持的编码方式
http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html
http://java.sun.com/j2se/1.4/docs/guide/intl/encoding.doc.html   


版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明


结论:

过以上几个Java试验程序得出的一些结论:

Java环境是基于操作系统上的一个虚拟机应用,因此,如果操作系统遵循国际化规范:JVM的缺省编码方式可以通过修改操作系统的LOCALE设置实现。对于一个Java应用来说,只要将LINUX的缺省编码方式设置成GBK,其文字编码处理应该和中文Windows平台上的表现是一致的。

    redhat 6.X使用linux内核的是基于glibc2.1.X,不支持中文LOCALE,因此无法通过改变LOCALE设置改变JVM的缺省编码方式,linux内核2.4开始基于glibc.2.2.x,对中文LOCALE有了比较好的支持。

不同的JVM对字符集的支持程度不同:
    比如:IBM的JVM1.3.0开始支持GB18030,SUN的JVM从1.4开始支持GB18030
正确的编码方式不一定表示能正确的显示,正确的显示还要需要相应的前端显示系统(字库)的支持
    但对于Linux上的服务应用来说,往往只要能确认字符正确的按照指定的方式编码就够了
如果应用的是基于UNICODE的编码方式处理并使用UTF8字符集做集中存储,这样最便于根据客户端语言环境做本地化输出;
根据以上结论,设计一个适应多语言环境的应用,可以考虑一下2个应用处理模式:

(客户端应用或本地化应用)根据LOCALE,让Java应用根据系统LOCALE的缺省的字符集设置进行切换,按系统缺省的字符集进行编码解码,减少应用在编码处理上的复杂程度。
输入字节流 ==>;按系统语言字符集设置将字节流解码==>; UNICODE处理 ==>; 按系统语言字符集设置将UNICODE编码成字节流 ==>; 输出字节流
   
(服务器端或跨语言平台应用):在应用的最外端:数据输入输出判断用户语言环境,核心按照UNICODE方式处理存储。可以把各种区域性的字符集(GB2312 BIG5)看成是UNICODE的一个子集。UNICODE存储的数据可以方便的转换成任意字符集。
应用使用UTF8方式存储虽然要增加了存储空间,但也可以大大简化前端应用本地化(i10n)的复杂程度。     
简体中文输入 繁体中文输入                 简体中文输出 繁体中文输出        \   /                                     \     /   判断用户语言环境:解码            判断用户语言环境:编码                  \                  /                  中间处理过程:UNICODE                           |                      UTF8编码存储
随着UNICODE被愈来愈多的系统和平台支持:Python Perl Glibc等,但我们应该珍惜一开始就按照国际化规范设计Java,并将其和新发展起来的XML规范相配合,相信符合国际化规范的应用设计从长远来看会展现出更多的优势。

论坛徽章:
0
2 [报告]
发表于 2003-09-26 11:25 |只看该作者

Java中文处理学习笔记——Hello Unicode 【转贴】

一点主权问题
Country                                         A 2     A 3     Number
----------------------------------------------------------------------
TAIWAN                                          TW      TWN     158
CHINA                                            CN      CHN     156

http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

"This file lists the codes for each country provided in ISO 3166. There are two tables: existing codes and withdrawn codes (codes can be withdrawn because the country no longer exists, the name has significantly changed, or one or more codes has altered)."


  

论坛徽章:
0
3 [报告]
发表于 2003-09-26 13:58 |只看该作者

Java中文处理学习笔记——Hello Unicode 【转贴】

不如统计一下有那些系统,版本还不能支持UNICODE的。
我用过SCO UNIXWARE7.11不行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP