JAVA及相关字符集编码问题研究

2016-01-29 12:03 3 1 收藏

JAVA及相关字符集编码问题研究,JAVA及相关字符集编码问题研究

【 tulaoshi.com - Java 】

关于JAVA学习者们,或多或少都会遇到这样的问题:编码基本知识,java,系统软件,url,工具软件等。

下面本文将针对以上几点问题进行描述讨论,我们就以“中文”两个字为例来说明,查找相关资料可知“中文”的GB2312编码是“d6d0 cec4”,为Unicode编码为"4e2d 6587",UTF编码就是"e4b8ad e69687"。(注意,“中文”这两个字没有iso8859-1编码,但可以用iso8859-1编码来"表示")。


一、编码基本知识:


最早的编码是iso8859-1,和ascii编码相似。但为了方便表示各种各样的语言,逐渐出现了很多标准编码,重要的有如下几个:


1. iso8859-1


属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母a的编码为0x61=97。


很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,虽然"中文"两个字不存在iso8859-1编码,以gb2312编码为例,应该是"d6d0 cec4"两个字符,使用iso8859-1编码的时候则将它拆开为4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时候,也是以字节为单位处理的)。而如果是UTF编码,则是6个字节"e4 b8 ad e6 96 87"。很明显,这种表示方法还需要以另一种编码为基础。


2. GB2312/GBK


这就是汉子的国标码,专门用来表示汉字,是双字节编码,而英文字母和iso8859-1一致(兼容iso8859-1编码)。其中gbk编码能够用来同时表示繁体字和简体字,而gb2312只能表示简体字,gbk是兼容gb2312编码的。


3. unicode


这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,包括英文字母在内。所以可以说它是不兼容iso8859-1编码的,也不兼容任何编码。不过,相对于iso8859-1编码来说,uniocode编码只是在前面增加了一个0字节,比如字母a为"00 61"。


需要说明的是,定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而unicode又可以用来表示所有字符,所以在很多软件内部是使用unicode编码来处理的,比如java。


4. UTF


考虑到unicode编码不兼容iso8859-1编码,而且容易占用更多的空间:因为对于英文字母,unicode也需要两个字节来表示。所以unicode不便于传输和存储。因此而产生了utf编码,utf编码兼容iso8859-1编码,同时也可以用来表示所有语言的字符,不过,utf编码是不定长编码,每一个字符的长度从1-6个字节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。


注意,虽然说utf是为了使用更少的空间而使用的,但那只是相对于unicode编码来说,如果已经知道是汉字,则使用GB2312/GBK无疑是最节省的。不过另一方面,值得说明的是,虽然utf编码对汉字使用3个字节,但即使对于汉字网页,utf编码也会比unicode编码节省,因为网页中包含了很多的英文字符。[next]二、java对字符的处理


在编写java应用程序中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地方需要进行一定程度的处理。


1. getBytes(charset)


这是java字符串处理的一个标准函数,其作用是将字符串所表示的字符按照charset编码,并以字节方式表示。注意字符串在java内存中总是按unicode编码存储的。比如"中文",正常情况下(即没有错误的时候)存储为"4e2d 6587",如果charset为"gbk",则被编码为"d6d0 cec4",然后返回字节"d6 d0 ce c4"。如果charset为"utf8"则最后是"e4 b8 ad e6 96 87"。如果是"iso8859-1",则由于无法编码,最后返回 "3f 3f"(注: "3f 3f"是两个问号)。


2. new String(charset)


这是java字符串处理的另一个标准函数,和上一个函数的作用相反,将字节数组按照charset编码进行组合识别,最后转换为unicode存储。参考上述getBytes的例子,"gbk" 和"utf8"都可以得出正确的结果"4e2d 6587",但iso8859-1最后变成了"003f 003f"(两个问号)。


因为utf8可以用来表示/编码所有字符,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。


3. setCharacterEncoding()


该函数用来设置http请求或者相应的编码。


对于request,是指提交内容的编码,指定后可以通过getParameter()则直接获得正确的字符串,如果不指定,则默认使用iso8859-1编码,需要进一步处理。参见下述"表单输入"。值得注意的是在执行setCharacterEncoding()之前,不能执行任何getParameter()。java doc上说明:This method must be called prior to reading request parameters or reading input using getReader()。而且,

来源:http://www.tulaoshi.com/n/20160129/1484385.html

延伸阅读
1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数? 可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。 调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。 2. 如何对DBCS(双字节字符集)字符串...
我在写一个查询条件时的问题如下: 如我想写一个字段中包含“李”字的所有记录 ?$str="李"; select * from table where field like ''%?$str%'' ; 显示的记录中除了包含”李”字的记录,还有不包含“李”字的记录。为什么? 在MySQL中,进行中文排序和查找的时候,对汉字的排序和查找结果是错误的。这种情况在MySQL的很...
1.character_set_server和collation_server 这两个变量是服务器的字符集。在系统启动的时候可以通过--character-set-server和--collation-server来设置它们。如果没有的话系统会把这两各变量设置成默认值latin1和latin1_swedish_ci。默认值是编译在程序中的,只能通过重新编译来改变。 这两个变量只用来为create database命令提供默认值。 ...
标签: MySQL mysql数据库
摘于:  http://jjgod.3322.org/2005/07/31/a-mysql-41-story/ 下面要写的是一篇非常无聊的东西,充斥了大量各式各样的编码、转换、客户端、服务器端、连接……呃,我自己都不愿意去看它,但想一想,写下来还是有点意义的,原因有四: MySQL 4.1 对多语言的支持有了很大变化 (这导致了问题的出现);  尽管大部分的地方 (包括个...
  (最近修正:2000/7/28)  分享imp 附件另存时的档名问题(2000/7/28) (颜国雄): imp(2.0.11) 在处理用 Outlook 寄来的附件档,下载的部份少了一个将档名解码的动作,以致於无法正确的抓到原来的档名,不过,这锅好像还是得怪 Outlook 老用自己的标准!! 解决的方法很简单,只要在 imp/view.php3&n...

经验教程

41

收藏

72
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部