GB2312是對(duì)中國(guó)的開發(fā)人員來說很重要的一個(gè)詞匯,它的來龍去脈并不需要我在這里贅述,隨便Google之便明白無誤。我只是想提一句,記得前一節(jié)說到編碼字符集和字符集編碼不是一回事,而有的字符集編碼又實(shí)際上沒有做任何事,GB2312正是這樣一種東西!
GB2312最初指的是一個(gè)編碼字符集,其中包含了ASCII所包含的英文字符,同時(shí)加入了6763個(gè)簡(jiǎn)體漢字以及其他一些ASCII之外的符號(hào)。與Unicode有UTF-8和UTF-16一樣(當(dāng)然, UTF-8和UTF-16也沒有被限定只能用來對(duì)Unicode進(jìn)行編碼,實(shí)際上,你用它對(duì)視頻進(jìn)行編碼都是可以的,只是編出的文件沒有播放器支持罷了,哈哈),GB2312也有自己的編碼方案,但這個(gè)方案直接使用一個(gè)字符在GB2312中的編號(hào)作為存儲(chǔ)值(與UTF-32的做法類似),也因此,這個(gè)編碼方案甚至沒有正式的名稱。我們?nèi)粘Uf起GB2312的時(shí)候,常常即指這個(gè)字符集,也指這種編碼方案。
GBK是GB2312的后續(xù)標(biāo)準(zhǔn),添加了更多的漢字和特殊符號(hào),類似的是,GBK也是同時(shí)指他的字符集和他的編碼。
GBK還是現(xiàn)如今中文Windows操作系統(tǒng)的系統(tǒng)默認(rèn)編碼(這正是幾乎所有網(wǎng)頁(yè)上的,文件里的亂碼問題的根源)。
我們可以這樣來驗(yàn)證,使用以下的Java代碼:
String encoding=System.getProperty("file.encoding");
System.out.println(encoding);


輸出結(jié)果為
              GBK
(什么?你的輸出不是這樣?怎么可能?完了,我的牌子要砸了,等等,你用的繁體版XP?我說你這同志在這里搗什么亂?去!去!)
說到GB2312和GBK就不得不提中文網(wǎng)頁(yè)的編碼。盡管很多新開發(fā)的Web系統(tǒng)和新上線的注重國(guó)際化的網(wǎng)站都開始使用UTF-8,仍有相當(dāng)一部分的中文媒體堅(jiān)持使用GB2312和GBK,例如新浪的頁(yè)面。其中有兩點(diǎn)很值得注意。
第一,頁(yè)面中meta標(biāo)簽的部分,常常可以見到
charset=GB2312
這樣的寫法,很不幸的是,這個(gè)“charset”其實(shí)是用來指定頁(yè)面使用的是什么字符集編碼,而不是使用什么字符集。例如你見到過有人寫“charset=UTF-8”,見到過有人寫“charset=ISO-8859-1”,但你見過有人寫“charset=Unicode”么?當(dāng)然沒有,因?yàn)閁nicode是一個(gè)字符集,而不是編碼。
然而正是charset這個(gè)名稱誤導(dǎo)了很多程序員,真的以為這里要指定的是字符集,也因而使他們進(jìn)一步的誤以為UTF-8和UTF-16是一種字符集!(萬惡啊)好在XML中已經(jīng)做出了修改,這個(gè)位置改成了正確的名稱:encoding。
第二,頁(yè)面中說的GB2312,實(shí)際上并不真的是GB2312(驚訝么?)。我們來做個(gè)實(shí)驗(yàn),例如找一個(gè)GB2312中不存在的漢字“亸”(這個(gè)字確實(shí)不在GB2312中,你可以到GB2312的碼表中去找,保證找不到),這個(gè)字在GBK中。然后你把它放到一個(gè)html頁(yè)面中,試著在瀏覽器中打開它,然后選擇瀏覽器的編碼為“GB2312”,看到了什么?它完全正常顯示!
結(jié)論不用我說你也明白了,瀏覽器實(shí)際上使用的是GBK來顯示。
新浪的頁(yè)面中也有很多這樣的例子,到處都寫charset=GB2312,卻使用了無數(shù)個(gè)GB2312中并不存在的字符。這種做法對(duì)瀏覽器顯示頁(yè)面并不成問題,但在需要程序抓取頁(yè)面并保存的時(shí)候帶來了麻煩,程序?qū)⒉荒芤罁?jù)頁(yè)面所“聲稱”的編碼進(jìn)行讀取和保存,而只能盡量猜測(cè)正確的編碼。