posts - 0, comments - 77, trackbacks - 0, articles - 356
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          日歷

          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          隨筆分類

          隨筆檔案(1)

          收藏夾(18)

          搜索

          •  

          最新評論

          Java 字符集編碼

          Posted on 2007-08-10 14:04 semovy 閱讀(3466) 評論(1)  編輯  收藏 所屬分類: JAVA基礎(chǔ)
          首先看清楚幾種常用的字符集編碼(java語言是采用unicode字符集編碼來表示字符與字符串的):

            ASCII(American Standard Code for Information Interchange,美國信息互換標(biāo)準(zhǔn)代碼),是基于常用的英文字符的一套電腦編碼系統(tǒng)。我們知道英文中經(jīng)常使用的字符、數(shù)字符號被計(jì)算機(jī)處理時都是以二進(jìn)制碼的形式出現(xiàn)的。這種二進(jìn)制碼的集合就是所謂的ASCII碼。每一個ASCII碼與一個8位(bit)二進(jìn)制數(shù)對應(yīng)。其最高位是0,相應(yīng)的十進(jìn)制數(shù)是0-127。如,數(shù)字“0”的編碼用十進(jìn)制數(shù)表示就是48。另有128個擴(kuò)展的ASCII碼,最高位都是1,由一些制表符和其它符號組成。ASCII是現(xiàn)今最通用的單字節(jié)編碼系統(tǒng)。

            GB2312:GB2312碼是中華人民共和國國家漢字信息交換用編碼,全稱《信息交換用漢字編碼字符集-基本集》。主要用于給每一個中文字符指定相應(yīng)的數(shù)字,也就是進(jìn)行編碼。一個中文字符用兩個字節(jié)的數(shù)字來表示,為了和ASCII碼有所區(qū)別,將中文字符每一個字節(jié)的最高位置都用1來表示。

            GBK:為了對更多的字符進(jìn)行編碼,國家又發(fā)布了新的編碼系統(tǒng)GBK(GBK的K是“擴(kuò)展”的漢語拼音第一個字母)。在新的編碼系統(tǒng)里,除了完全兼容GB2312 外,還對繁體中文、一些不常用的漢字和許多符號進(jìn)行了編碼。

            ISO-8859-1:是西方國家所使用的字符編碼集,是一種單字節(jié)的字符集 ,而英文實(shí)際上只用了其中數(shù)字小于128的部分。

            Unicode:這是一種通用的字符集,對所有語言的文字進(jìn)行了統(tǒng)一編碼,對每一個字符都用2個字節(jié)來表示,對于英文字符采取前面加“0”字節(jié)的策略實(shí)現(xiàn)等長兼容。如 “a” 的ASCII碼為0x61,UNICODE就為0x00,0x61。

            UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集標(biāo)準(zhǔn)的一個超集)。一個7位的ASCII碼值,對應(yīng)的UTF碼是一個字節(jié)。如果字符是0x0000,或在0x0080與0x007f之間,對應(yīng)的UTF碼是兩個字節(jié),如果字符在0x0800與0xffff之間,對應(yīng)的UTF碼是三個字節(jié)。

            我們運(yùn)行java程序時,JVM有自己所支持的編碼種類,用以下代碼可以看到:

          Map m = Charset.availableCharsets();
             Set names
          = m.keySet();
             Iterator it
          = names.iterator();
            
          while (it.hasNext())
            
          {
              System.out.println(it.next());
             }


             然后可以通過以下代碼看到我們目前JVM所使用的編碼:

          Properties pps = System.getProperties();
             pps.list(System.out);

            具體來說什么是編碼,什么是解碼?
            在InputStreamReader JDK有這樣描述:It reads bytes and decodes them into characters using a specified charset.(用指定的字符集將字節(jié)數(shù)組解碼成字符串)。
            相反OutputStreamWriter 描述:Characters written to it are encoded into bytes using a specified charset.(用指定的字符集將字符串編碼成字節(jié)數(shù)組)。

            理解這個以后一切好辦了啦!

            我們的OS一般是GBK編碼的(凡是從磁盤上讀取文件可以看成是用OS的字符集編碼方式來對操作對象進(jìn)行解碼處理--從標(biāo)準(zhǔn)輸入設(shè)備讀取數(shù)據(jù)的時候是依賴OS的字符集)。而我們將從磁盤上文件經(jīng)過處理得到我們想要的字符串等其它對象的時候,這一過程是用JVM的默認(rèn)的字符集編碼方式來處理的!由于不同的字符集編碼方式有著不同的原理(前面所述),這樣當(dāng)編碼與解碼不一致的時候,自然而然就出現(xiàn)了可愛的亂碼。

            比如如下,將我們JVM字符集改成iso-8859-1這樣在就與我們的OS不同:
            當(dāng)輸入中文時自然就輸出的是亂碼了。

          pps.put( " file.encoding " , " ISO-8859-1 " );
            
          int data;
            
          byte [] buf = new byte [ 100 ];
            
          int i = 0 ;
            
          while ((data = System.in.read()) != ' q ' )
            
          {
              buf[i]
          = ( byte )data;
              i
          ++ ;
             }

             String str
          = new String(buf, 0 ,i);
             System.out.println(str);

           
            這時我們可以用string的一個構(gòu)造方法:
            String(byt[] bytes, String charsetName)
            Constructs a
          new String by decoding the specified array of bytes using the specified charset.(用指定的字符集對字節(jié)數(shù)組進(jìn)行解碼)。
            其中用到了string 的getBytes方法:
            getBytes(String charsetName)
            Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.(用指定的字符集進(jìn)行編碼,將結(jié)果存放到一字節(jié)數(shù)組里面)重新構(gòu)造一個string:

          String strGBK = new String(str.getBytes( " ISO-8859-1 " ), " GBK " );

            這樣又可以重新得到我們想要的漢字了。

            我們這例子中是GBK(OS)來編碼的,然后采用iso-8859-1(JVM)來解碼得到一個新string(此string是亂碼),然后將此string用iso-8859-1重新編碼,并且用指定的GBK來解碼。得到一個新string(也就是strGBK),這個string就不再是亂碼了。

            但如果我們一開始就采用GBK解碼得到的字符串,然后用ISO-8859-1編碼,能否再解碼回去得到我們的中文字符呢?顯示不可以啦,因?yàn)橛肐SO-8859-1的編碼的時候采用是一種單字節(jié)的字符集來對其編碼,這樣就丟失了一個字節(jié)(對中文來說)!所以這樣是得不到中文字符的!


          評論

          # re: Java 字符集編碼  回復(fù)  更多評論   

          2010-02-24 18:01 by fdsafd
          文章寫的很好
          主站蜘蛛池模板: 苍梧县| 盐源县| 宜兰市| 巴彦淖尔市| 玉溪市| 广宁县| 鄱阳县| 辰溪县| 孟州市| 台南县| 昌宁县| 襄汾县| 车致| 长乐市| 乡城县| 宾阳县| 彭阳县| 乌恰县| 商南县| 沐川县| 自贡市| 大悟县| 乌兰浩特市| 常宁市| 磐石市| 双江| 内黄县| 岳普湖县| 玛纳斯县| 丹江口市| 信丰县| 丹棱县| 霍州市| 大方县| 伊宁市| 盘山县| 上饶市| 白朗县| 元阳县| 宜君县| 道真|