Java中的字符集编码入门(三)GB2312,GBK与中文网页
Java中的字符集编码入门(三)GB2312,GBK与中文网页
GB2312是对中国的开发人员来说很重要的一个词汇,它的来龙去脉并不需要我在这里赘述,随便Goolge之便明白无误。我只是想提一句,记得前一节说到编码字符集和字符集编码不是一回事,而有的字符集编码又实际上没有做任何事,GB2312正是这样一种东西!
GB2312最初指的是一个编码字符集,其中包含了ASCII所包含的英文字符,同时加入了6763个简体汉字以及其他一些ASCII之外的符号。与Unicode有UTF-8和UTF-16一样(当然, UTF-8和UTF-16也没有被限定只能用来对Unicode进行编码,实际上,你用它对视频进行编码都是可以的,只是编出的文件没有播放器支持罢了,哈哈),GB2312也有自己的编码方案,但这个方案直接使用一个字符在GB2312中的编号作为存储值(与UTF-32的做法类似),也因此,这个编码方案甚至没有正式的名称。我们日常说起GB2312的时候,常常即指这个字符集,也指这种编码方案。
GBK是GB2312的后续标准,添加了更多的汉字和特殊符号,类似的是,GBK也是同时指他的字符集和他的编码。
GBK还是现如今中文Windows操作系统的系统默认编码(这正是几乎所有网页上的,文件里的乱码问题的根源)。
我们可以这样来验证,使用以下的Java代码:
1 | String encoding=System.getProperty("file.encoding"); |
输出结果为GBK (什么?你的输出不是这样?怎么可能?完了,我的牌子要砸了,等等,你用的繁体版XP?我说你这同志在这里捣什么乱?去!去!)
说到GB2312和GBK就不得不提中文网页的编码。尽管很多新开发的Web系统和新上线的注重国际化的网站都开始使用UTF-8,仍有相当一部分的中文媒体坚持使用GB2312和GBK,例如新浪的页面。其中有两点很值得注意。
第一,页面中meta标签的部分,常常可以见到charset=GB2312这样的写法,很不幸的是,这个“charset”其实是用来指定页面使用的是什么字符集编码,而不是使用什么字符集。例如你见到过有人写“charset=UTF-8”,见到过有人写“charset=ISO-8859-1”,但你见过有人写“charset=Unicode”么?当然没有,因为Unicode是一个字符集,而不是编码。
然而正是charset这个名称误导了很多程序员,真的以为这里要指定的是字符集,也因而使他们进一步的误以为UTF-8和UTF-16是一种字符集!(万恶啊)好在XML中已经做出了修改,这个位置改成了正确的名称:encoding.第二,页面中说的GB2312,实际上并不真的是GB2312(惊讶么?)。我们来做个实验,例如找一个GB2312中不存在的汉字“亸”(这个字确实不在GB2312中,你可以到GB2312的码表中去找,保证找不到),这个字在GBK中。然后你把它放到一个html页面中,试着在浏览器中打开它,然后选择浏览器的编码为“GB2312”,看到了什么?它完全正常显示!
结论不用我说你也明白了,浏览器实际上使用的是GBK来显示。
新浪的页面中也有很多这样的例子,到处都写charset=GB2312,却使用了无数个GB2312中并不存在的字符。这种做法对浏览器显示页面并不成问题,但在需要程序抓取页面并保存的时候带来了麻烦,程序将不能依据页面所“声称”的编码进行读取和保存,而只能尽量猜测正确的编码。