Java學(xué)習(xí)

          java,spring,structs,hibernate,jsf,ireport,jfreechart,jasperreport,tomcat,jboss -----本博客已經(jīng)搬家了,新的地址是 http://www.javaly.cn 如果有對(duì)文章有任何疑問(wèn)或者有任何不懂的地方,歡迎到www.javaly.cn (Java樂(lè)園)指出,我會(huì)盡力幫助解決。一起進(jìn)步

           

          java字符丟失與中文編碼

          java字符丟失與中文編碼    警告:編碼 utf8 的不可映射字符   獲得ConnectionManager,設(shè)置相關(guān)參數(shù)   警告:編碼 utf8 的不可映射字符 標(biāo)志初始化是否完成的flag

          關(guān)鍵字: java字符丟失與中文編碼 1.       引言
          在用JAVA進(jìn)行開(kāi)發(fā)時(shí),偶爾在IO操作中會(huì)產(chǎn)生字符丟失現(xiàn)象。如在用BEA的WORKSHOP開(kāi)發(fā)CMP EJB過(guò)程中,總是編譯不通過(guò),報(bào)錯(cuò):

          cannot resolve symbol

          symbol  : class Excetion

          location: class eaitest.vip.firmorder.FirmOrderBean_g8ghds__WebLogic_CMP_RDBMS

              } catch (Excetion ex) {

          可以看到明顯“Excetion”拼寫(xiě)錯(cuò)誤。而這段代碼是WORKSHOP自動(dòng)生成。但是,在某些機(jī)器上,同樣的工程文件,編譯就能通過(guò)。聯(lián)系BEA工程師,也不能解決此問(wèn)題。

          筆者查閱大量資料,很難找到相關(guān)問(wèn)題的介紹。一次在偶爾查閱SUN的缺陷庫(kù)[i]時(shí),發(fā)現(xiàn)是由于GB18030中文編碼問(wèn)題所致。

          2.       問(wèn)題分析
          國(guó)家標(biāo)準(zhǔn)GB18030-2000《信息交換用漢字編碼字符集基本集的擴(kuò)充》是我國(guó)繼GB2312-1980和GB13000-1993之后最重 要的漢字編碼標(biāo)準(zhǔn),是我國(guó)計(jì)算機(jī)系統(tǒng)必須遵循的基礎(chǔ)性標(biāo)準(zhǔn)之一。國(guó)家質(zhì)監(jiān)總局規(guī)定GB 18030過(guò)渡期(即2001年8月31日)后正式發(fā)布或出廠的產(chǎn)品,必須符合GB-18030相關(guān)要求。

          操作系統(tǒng)默認(rèn)內(nèi)部編碼一般并不是GB18030,目前已知在WINDOWS XP操作系統(tǒng)中,進(jìn)行某些組件的升級(jí)后,會(huì)把操作系統(tǒng)的默認(rèn)編碼由GB2312變更為GB18030。

          但是即便在最新發(fā)布的JDK1.4.2_06版本中,對(duì)其支持仍存在一定問(wèn)題。GB18030問(wèn)題主要表現(xiàn)是,基于java的應(yīng)用,涉及GB18030編碼與其它編碼方案轉(zhuǎn)換時(shí),存在字符丟失現(xiàn)象。

          問(wèn)題的原因是java在處理由sun.nio.cs.ext.ExtendedCharsets提供的擴(kuò)展字符集時(shí),會(huì)進(jìn)行字符緩沖。但是對(duì)于緩 沖字符沒(méi)有采用新的sun.nio.cs.ext包處理,而是延用原有處理方式,這種方式在多線程操作下對(duì)GB18030編碼方案處理存在問(wèn)題,這樣導(dǎo)致 部分字符丟失。

          此問(wèn)題只影響GB18030編碼方案,對(duì)GB2312等中文編碼方案并沒(méi)有影響。

          當(dāng)操作系統(tǒng)默認(rèn)編碼方案為GB18030時(shí),如果進(jìn)行文件寫(xiě)操作,未指定編碼方案情況下,java采用操作系統(tǒng)默認(rèn)編碼方案操作,這時(shí)最容易出現(xiàn)GB18030問(wèn)題。

          查看操作系統(tǒng)默認(rèn)編碼,可以運(yùn)行如下java程序:

          public class EchoDefaultSystemEncoding{

              public static void main(String[] args){

                  String encoding=System.getProperty(“file.encoding”);

                  System.out.println(“Default System Encoding: ” + encoding);

              }

          }

          在用WORKSHOP開(kāi)發(fā)CMP EJB出現(xiàn)問(wèn)題的操作系統(tǒng)默認(rèn)編碼即為GB18030。

          由于遇到此問(wèn)題的人比較少。而真正遇到時(shí),很多人通過(guò)重新安裝操作系統(tǒng)可以解決問(wèn)題,因而這方面的資料很難找到。

          3.       解決辦法
          最理想的解決辦法就是由SUN修正此BUG。此問(wèn)題早在2003年11月即提出,但是直到目前(2004/12/30),問(wèn)題狀態(tài)仍為“In process, bug”。

          替代的解決方案主要思路是避開(kāi)GB18030編碼,主要有兩種方法

          改變操作系統(tǒng)默認(rèn)編碼方案

          對(duì)于unix/linux平臺(tái),修改操作系統(tǒng)編碼方案很簡(jiǎn)單。如在solaris平臺(tái)下,運(yùn)行如下命令即可改變系統(tǒng)編碼:

          LANG=zh.GBK;export LANG

          對(duì)于windows平臺(tái),修改操作系統(tǒng)中文默認(rèn)編碼比較復(fù)雜。嘗試把操作系統(tǒng)的“區(qū)域和語(yǔ)言選項(xiàng)”更改為其它地區(qū),選用其它語(yǔ)言,都沒(méi)有效果。與微軟客戶服務(wù)聯(lián)系,也不能提供相應(yīng)解決方案。

          運(yùn)行java應(yīng)用時(shí)指定默認(rèn)編碼

          在運(yùn)行基于JAVA的應(yīng)用時(shí),加上參數(shù):

          java –Dfile.encoding=GB2312

          把java應(yīng)用的默認(rèn)編碼方案與GB2312硬綁定,即在未指明編碼方案時(shí),采用GB2312編碼。

          如果針對(duì)每個(gè)應(yīng)用,進(jìn)行上述修改,工作量很大。有些應(yīng)用里面又隱式調(diào)用外部JAVA應(yīng)用,更增加修正的難度。比較可行的辦法是對(duì)java的運(yùn)行文件進(jìn)行修正,令其在運(yùn)行時(shí)自動(dòng)加上“-Dfile.encoding=GB2312”參數(shù)。

          建議windows平臺(tái)采用本方法進(jìn)行修正。方案如下:

          1、改名原java.exe,javaw.exe,如改為javabak.exe,javawbak.exe

          2、重寫(xiě)java.exe和javaw.exe,令其運(yùn)行時(shí)調(diào)用javabak.exe,javawbak.exe,并在運(yùn)行時(shí)加上“-Dfile.encoding”參數(shù)。

          如下c代碼即可完成上述功能:

          #include "string.h"

          #include "stdlib.h"



          int main(int argc, char* argv[])

          {

              char arg[100000] = "javabak.exe -Dfile.encoding=GB2312 ";

              for(int i=1; i<argc; i++){

                  strcat(arg,argv[i]);

                  strcat(arg, " ");

              }

              system(arg);

              return 0;

          }

          編譯后(注意修改arg值),生成的文件命名為java.exe和javaw.exe,放置在<JAVA_HOME>/bin和<JAVA_HOME>/jre/bin目錄下,即可。

          經(jīng)實(shí)踐,此辦法可以解決GB18030問(wèn)題,并且不會(huì)帶來(lái)其它隱患。唯一的缺點(diǎn)是在運(yùn)行JAVA應(yīng)用時(shí),會(huì)有一個(gè)額外的DOS窗口打開(kāi),此窗口可以關(guān)閉,不會(huì)對(duì)應(yīng)用運(yùn)行帶來(lái)影響。

          4.       總結(jié)
          在應(yīng)用開(kāi)發(fā)中,中文編碼一直是一個(gè)比較麻煩的問(wèn)題。盡管目前GB18030是國(guó)家強(qiáng)制性標(biāo)準(zhǔn),有著各種各樣的優(yōu)點(diǎn),但由于其推出時(shí)間尚短,在應(yīng)用方面對(duì)其支持還不夠完善,還是應(yīng)盡可能采用GB2312等兼容性比較強(qiáng)的中文編碼方案。

          本文給出的解決方案,不僅適用于解決JAVA平臺(tái)對(duì)GB18030支持問(wèn)題,而且,也為指定通用JAVA運(yùn)行默認(rèn)參數(shù),提供了另一種思路。



          --------------------------------------------------------------------------------

          參考文獻(xiàn)

          [i] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4954023

          posted on 2009-05-20 12:54 找個(gè)美女做老婆 閱讀(262) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          本blog已經(jīng)搬到新家了, 新家:www.javaly.cn
           http://www.javaly.cn

          常用鏈接

          留言簿(6)

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 洪雅县| 习水县| 额敏县| 全南县| 邓州市| 栖霞市| 怀仁县| 绥中县| 蓝山县| 镇远县| 马边| 漳浦县| 四会市| 乌鲁木齐县| 郴州市| 陆丰市| 盐边县| 中江县| 高安市| 南漳县| 金山区| 历史| 铜梁县| 长沙市| 三河市| 时尚| 嘉祥县| 宁乡县| 堆龙德庆县| 通山县| 永寿县| 永丰县| 花垣县| 玉龙| 板桥市| 五大连池市| 元朗区| 武乡县| 阿拉善左旗| 金堂县| 蒙自县|