java中文问题已经是个老大难问题了,网上也好很多相关的文章,有的对原理进行了深入的分析,有的提出了解决方案。当问题出现的时候,google,baidu一下,然后根据,糊弄几下,确实有立杆见影的效果。但是,每次都这样子缝缝补补总让人放不下心呐,万一哪天又出问题,都不知道是哪里出了漏子。知其然不知其所以然的事情,还是少做为妙。
本人就曾经跟java中文问题有过一次“美丽的邂逅”,其中的缠绵悱恻已是不堪回首。趁着最近有时间 ,决定跟它做一个彻底的了断,于是就有了这一系列的文章。(过程是有点痛苦,花了额整整两天,人都憔悴了。。)
一、什么是java中文问题
简单作一个定义吧(自己搞的,看看就好,呵呵):所谓java中文问题是指在使用java环境的过程中由于某种原因导致中文数据不能被正确显示和记录的现象。什么时候会出现这个问题呢?举几个例子吧:当你在中文平台下用编辑器编写好含有中文的java源代码(实现控制台输出之类的),然后把它放到一个英文平台中用javac按照默认设置进行编译,执行的时候中文问题就出现了。还有一个例子就是编写java web应用的时候,当jsp、servlet中没有设置好页面的编码方式或者输入输出时的编码解码方式时,也会出现中文问题。说起来蛮抽象的,不过现在只要了解java中文问题不是别的,就是中文在使用java的过程中没有得到正确的处理,导致乱码现象的出现。还有一点就是,所谓的“中文问题”并不是只有中文才会遭遇这类问题,其实其它使用非英文(西欧)文字的国家和地区,譬如日本,韩国,香港,台湾等都会有这种问题的,只是我们用“中文问题”做一个代表而已。
二、为什么java会产生中文问题
要了解这个问题,就要有字符集(charset)和字符编码(encoding)的概念了。字符集说明了哪些字符被收集到标准中,而编码则是说明字符集里面的字符是怎样存储的,是用一个字节还是多个字节。我们也可以这样理解,字符集就像我们的语言,像汉语,英语,法语之类的;而字符编码就是各种语言相应的文字,是表明如何记录和书写的。文字可以记录在纸上,而字符编码可以写入到文件中。我们看到纸上那个符号,就知道那代表了什么意义了;计算机一读到文件中的那个编码,也知道它代表什么含义。人的世界里语言各色各样,计算机世界里的字符集也不少,我们常用的就有ASCII,ISO-8859-1,GB2312,GBK,BIG5,Unicode(UTF-8,UTF-16)等等。
字符集那么多,而字符编码的方案就那么几个(无非就是单字节,双字节,多字节),因此肯定会出现“撞车”现象。都是记录在文件中的编码“0xBA 0xBA”,在GBK看来就是一个“汉”字,但是在ISO-8859-1看来却变成了两个“?”,说是认不到。这就像一个纸上写着个“爹”,我们都知道汉语里那是老爸的意思,但是跑到日语里,就不知变成什么意思了。最要命的是,如果没有上下文指明这是汉字还是日本字,那么就算有一个人精通这两种语言,对于如何解析也是无从下手的。java面临的就是这样的问题,因为java内部是Unicode的,因此理论上可以处理世界上任何一种字符编码。但是java运行在这样一个纷繁复杂的世界中,要处理各色各样的输入和输出,要和各种字符集打交道。我们在使用java的时候,至少给java通知一声,说我现在给你的是GBK的哦,你给我输出为ISO-8859-1的,那边的猪头只认识那些英文字符的。OK,马上,java知道以后,就可以正确完成你所布置的任务了。
但是,如果你什么都不说,java只好按照默认的方式进行工作了。假设java的默认方式是按照GBK读写的,但是有一天,你给了java一段utf-8的数据,又没有跟它指明,好了,中文问题就来了。此情此景,就像某人递给你一张纸条,上书“奸爸爹”,却没告诉你这是日文,你就把它当中文理解,于是×※##¥。。
所以啊,说到底,java中文问题就是因为在使用java处理输入输出的过程中没有进行正确的设置而导致的。你可能会说,怎么这么麻烦啊,怎么不见人家php,asp会出现这种问题。呵呵,因为你要享受java“一次编译,到处运行”的好处,就必须付出点代价,上帝是很公平的。
三、如何解决java中文问题
好了,我认了,那怎么解决呢?具体问题具体分析。java中文问题的具体原因有很多,随着所处的环境的不同,解决方法也有所差异。具体的解决方法会在后续的文章中一一给出。
深入浅出Java中文问题(二)字符,字节和编码
深入浅出java中文问题(三)console程序的中文问题
深入浅出java中文问题(四)Web应用中的中文问题
深入浅出java中文问题(五)数据库出现的中文问题
深入浅出Java中文问题(六) 文件读写
还加上一篇Python的 Python 中文问题研究