天下難事,必作于易;天下大事,必作于細(xì)
          如果我有方向,那就是遠(yuǎn)方
          posts - 11,comments - 8,trackbacks - 0
          1、函數(shù)介紹
          在Java中,字符串用統(tǒng)一的Unicode編碼,每個字符占用兩個字節(jié),與編碼有關(guān)的兩個主要函數(shù)為:
          1)將字符串用指定的編碼集合解析成字節(jié)數(shù)組,完成Unicode-〉charsetName轉(zhuǎn)換
          public byte[] getBytes(String charsetName) throws UnsupportedEncodingException 
          ?
          2)將字節(jié)數(shù)組以指定的編碼集合構(gòu)造成字符串,完成charsetName-〉Unicode轉(zhuǎn)換
          public String(byte[] bytes, String charsetName) throws UnsupportedEncodingException
          ?
          2、Unicode與各編碼之間的直接轉(zhuǎn)換
          下面以對中文字符串"a中文"的編碼轉(zhuǎn)換為例,來了解各種編碼之間的轉(zhuǎn)換
          1)Unicode和GBK
          測試結(jié)果如下,每個漢字轉(zhuǎn)換為兩個字節(jié),且是可逆的,即通過字節(jié)可以轉(zhuǎn)換回字符串
          StringGBKByteArray:\u0061\u4E2D\u6587(a中文)-〉0x61 0xD6 0xD0 0xCE 0xC4
          ByteArrayGBKString:0x61 0xD6 0xD0 0xCE 0xC4-〉\u0061\u4E2D\u6587(a中文)
          ?
          2)Unicode和UTF-8
          測試結(jié)果如下,每個漢字轉(zhuǎn)換為三個字節(jié),且是可逆的,即通過字節(jié)可以轉(zhuǎn)換回字符串
          StringUTF-8ByteArray:\u0061\u4E2D\u6587(a中文)-〉0x61 0xE4 0xB8 0xAD 0xE6%0x96 0x87
          ByteArrayUTF-8String:0x61 0xE4 0xB8 0xAD 0xE6%0x96 0x87-〉\u0061\u4E2D\u6587(a中文)
          3)Unicode和ISO-8859-1
          測試結(jié)果如下,當(dāng)存在漢字時轉(zhuǎn)換失敗,非可逆,即通過字節(jié)不能再轉(zhuǎn)換回字符串
          StringISO-8859-1ByteArray:\u0061\u4E2D\u6587(a中文)-〉0x61 0x3F 0x3F
          ByteArrayISO-8859-1String:0x61 0x3F 0x3F-〉\u0061\u003F\u003F(a??)
          3、Unicode與各編碼之間的交叉轉(zhuǎn)換
          在上面直接轉(zhuǎn)換中,由字符串(Unicode)生成的字節(jié)數(shù)組,在構(gòu)造回字符串時,使用的是正確的編碼集合,如果使用的不是正確的編碼集合會怎樣呢?會正確構(gòu)造嗎?如果不能正確構(gòu)造能有辦法恢復(fù)嗎?會信息丟失嗎?
          ?
          下面我們就來看看這種情況,這部分可以說明在某些情況下雖然我們最終正確顯示了結(jié)果,但其間仍然進(jìn)行了不正確的轉(zhuǎn)換。
          ?
          1)能夠正確顯示的中間不正確轉(zhuǎn)換
          我們知道StringGBKByteArrayGBKString是正確的,但如果我們采用StringGBKByteArrayISO-8859-1String呢?通過測試結(jié)果如下:
          StringGBKByteArrayISO-8859-1String:\u0061\u4E2D\u6587(a中文)-〉0x61 0xD6 0xD0 0xCE 0xC4-〉\u0061\u00D6\u00D0\u00CE\u00C4(a????)
          ?
          這時我們得到的字符串為?亂碼“a????”,但是通過繼續(xù)轉(zhuǎn)換我們?nèi)匀豢梢詮?fù)原回正確的字符串“a中文”,過程如下:
          StringGBKByteArrayISO-8859-1StringISO-8859-1ByteArrayGBKString
          對應(yīng):\u0061\u4E2D\u6587(a中文)-〉0x61 0xD6 0xD0 0xCE 0xC4-〉\u0061\u00D6\u00D0\u00CE\u00C4(a????)-〉0x61 0xD6 0xD0 0xCE 0xC4-〉\u0061\u4E2D\u6587(a中文)
          ?
          也就是我們在首次構(gòu)造字符串時,我們用了錯誤的編碼集合得到了錯誤的亂碼,但是我們通過錯上加錯,再用錯誤的編碼集合獲取字節(jié)數(shù)組,然后再用正確的編碼集合構(gòu)造,就又恢復(fù)了正確的字符串。這時就屬于是“能夠正確顯示的中間不正確轉(zhuǎn)換”。在Jsp頁面提交數(shù)據(jù)處理時常常發(fā)生這種情況。
          ?
          此外能夠正確顯示的中間不正確轉(zhuǎn)換還有:
          StringUTF-8ByteArrayISO-8859-1StringISO-8859-1ByteArrayUTF-8String
          StringUTF-8ByteArrayGBKStringGBKByteArrayUTF-8String
          對應(yīng):\u0061\u4E2D\u6587(a中文)-〉0x61 0xE4 0xB8 0xAD 0xE6%0x96 0x87-〉\u0061\u6D93\uE15F\u6783(a涓枃)-〉0x61 0xE4 0xB8 0xAD 0xE6%0x96 0x87-〉\u0061\u4E2D\u6587(a中文)
          ?
          4、編碼過程中錯誤診斷參考
          1)一個漢字對應(yīng)一個問號
          在通過ISO-8859-1從字符串獲取字節(jié)數(shù)組時,由于一個Unicode轉(zhuǎn)換成一個byte,當(dāng)遇到不認(rèn)識的Unicode時,轉(zhuǎn)換為0x3F,這樣無論用哪種編碼構(gòu)造時都會產(chǎn)生一個?亂碼。
          2)一個漢字對應(yīng)兩個問號
          在通過GBK從字符串獲取字節(jié)數(shù)組時,由于一個Unicode轉(zhuǎn)換成兩個byte,如果此時用ISO-8859-1或用UTF-8構(gòu)造字符串就會出現(xiàn)兩個問號。
          若是通過ISO-8859-1構(gòu)造可以再通過上面所說的錯上加錯恢復(fù)(即再通過從ISO-8859-1解析,用GBK構(gòu)造);
          若是通過UTF-8構(gòu)造則會產(chǎn)生Unicode字符"\uFFFD",不能恢復(fù),若再通過String-UTF-8〉ByteArray-GBK〉String,則會出現(xiàn)雜碼,如a錕斤拷錕斤拷
          3)一個漢字對應(yīng)三個問號
          在通過UTF-8從字符串獲取字節(jié)數(shù)組時,由于一個Unicode轉(zhuǎn)換成三個byte,如果此時用ISO-8859-1構(gòu)造字符串就會出現(xiàn)三個問號;用GBK構(gòu)造字符串就會出現(xiàn)雜碼,如a涓枃。
          posted on 2007-12-04 14:57 flyepp 閱讀(7521) 評論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 台湾省| 凤翔县| 翁源县| 昂仁县| 黑水县| 宝坻区| 深圳市| 中山市| 马尔康县| 云梦县| 宜城市| 天长市| 龙岩市| 余干县| 汉阴县| 施甸县| 奉化市| 阿克陶县| 文水县| 洛宁县| 乐都县| 涟源市| 临洮县| 武清区| 安义县| 禹城市| 西林县| 威远县| 绥阳县| 崇州市| 色达县| 岑溪市| 澎湖县| 日土县| 灌阳县| 吉水县| 承德市| 九龙城区| 泸西县| 甘南县| 怀柔区|