閱讀230 返回首頁    go 阿裏雲 go 技術社區[雲棲]


使用Java將中文字符轉換成Unicode編碼

 

這兩天操作XML使用到了Jdom,在創建XML文件並輸出到硬盤的時候遇到一個中文編碼的問題:Jdom默認輸出的XML編碼是UTF-8,但是文檔中如果出現中文字符那麼該中文字符就會變成亂碼,造成XML文件無法被正確解析。

UTF-8應該是可以用來表示中文的吧?我不知道這是不是Jdom的一個BUG(Jdom 1.0,beta了10次的產物哦!)。我google了一下,大家解決這個問題的辦法無非是把Jdom的輸出字符集改為GBK或者GB2312,但是這樣就會有一些副作用,如果在沒有特定字符集(GBK或者GB2312)的操作係統上不是依然不能正確解析嗎?一個比較好的解決辦法是先把中文轉換成Unicode編碼在直接輸出,程序解析XML後的時候再把Unicode編碼轉回中文就沒有問題了。

於是我查看了JDK的文檔,截至Java 5好像都沒有做類似轉換的類可以直接使用,但是我發現一個類 java.util.Properties,它的源代碼裏有兩個私有(private)方法 loadConvert (char[] in, int off, int len, char[] convtBuf) 和 saveConvert(String theString, boolean escapeSpace) 其實就是做特殊字符和Unicode編碼字符間轉換的,我把它們提取出來,單獨包裝到一個類裏就可以使用了。

下麵是我包裝的類 CharacterSetToolkit

/*
* CharacterSetToolkit.java
*
* Created on 2006年10月27日, 下午2:06
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package mobi.chenwei.lang;

/**
* 進行字符操作的工具類
* @author Chen Wei
* @email
chenwei.mobi@gmail.com
*/
public class CharacterSetToolkit {
    
     /** Creates a new instance of CharacterSetToolkit */
     public CharacterSetToolkit() {
     }
    
     private static final char[] hexDigit = {
         '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
     };
    
     private static char toHex(int nibble) {
         return hexDigit[(nibble & 0xF)];
     }
    
     /**
      * 將字符串編碼成 Unicode 。
      * @param theString 待轉換成Unicode編碼的字符串。
      * @param escapeSpace 是否忽略空格。
      * @return 返回轉換後Unicode編碼的字符串。
      */
     public static String toUnicode(String theString, boolean escapeSpace) {
         int len = theString.length();
         int bufLen = len * 2;
         if (bufLen < 0) {
             bufLen = Integer.MAX_VALUE;
         }
         StringBuffer outBuffer = new StringBuffer(bufLen);

         for(int x=0; x<len; x++) {
             char aChar = theString.charAt(x);
             // Handle common case first, selecting largest block that
             // avoids the specials below
             if ((aChar > 61) && (aChar < 127)) {
                 if (aChar == '\\') {
                     outBuffer.append('\\'); outBuffer.append('\\');
                     continue;
                 }
                 outBuffer.append(aChar);
                 continue;
             }
             switch(aChar) {
                 case ' ':
                     if (x == 0 || escapeSpace)
                         outBuffer.append('\\');
                     outBuffer.append(' ');
                     break;
                 case '\t':outBuffer.append('\\'); outBuffer.append('t');
                           break;
                 case '\n':outBuffer.append('\\'); outBuffer.append('n');
                           break;
                 case '\r':outBuffer.append('\\'); outBuffer.append('r');
                           break;
                 case '\f':outBuffer.append('\\'); outBuffer.append('f');
                           break;
                 case '=': // Fall through
                 case ':': // Fall through
                 case '#': // Fall through
                 case '!':
                     outBuffer.append('\\'); outBuffer.append(aChar);
                     break;
                 default:
                     if ((aChar < 0x0020) || (aChar > 0x007e)) {
                         outBuffer.append('\\');
                         outBuffer.append('u');
                         outBuffer.append(toHex((aChar >> 12) & 0xF));
                         outBuffer.append(toHex((aChar >>   8) & 0xF));
                         outBuffer.append(toHex((aChar >>   4) & 0xF));
                         outBuffer.append(toHex( aChar         & 0xF));
                     } else {
                         outBuffer.append(aChar);
                     }
             }
         }
         return outBuffer.toString();
     }
    
     /**
      * 從 Unicode 碼轉換成編碼前的特殊字符串。
      * @param in Unicode編碼的字符數組。
      * @param off 轉換的起始偏移量。
      * @param len 轉換的字符長度。
      * @param convtBuf 轉換的緩存字符數組。
      * @return 完成轉換,返回編碼前的特殊字符串。
      */
     public String fromUnicode(char[] in, int off, int len, char[] convtBuf) {
         if (convtBuf.length < len) {
             int newLen = len * 2;
             if (newLen < 0) {
                 newLen = Integer.MAX_VALUE;
             }
             convtBuf = new char[newLen];
         }
         char aChar;
         char[] out = convtBuf;
         int outLen = 0;
         int end = off + len;

         while (off < end) {
             aChar = in[off++];
             if (aChar == '\\') {
                 aChar = in[off++];
                 if (aChar == 'u') {
                     // Read the xxxx
                     int value = 0;
                     for (int i = 0; i < 4; i++) {
                         aChar = in[off++];
                         switch (aChar) {
                         case '0':
                         case '1':
                         case '2':
                         case '3':
                         case '4':
                         case '5':
                         case '6':
                         case '7':
                         case '8':
                         case '9':
                             value = (value << 4) + aChar - '0';
                             break;
                         case 'a':
                         case 'b':
                         case 'c':
                         case 'd':
                         case 'e':
                         case 'f':
                             value = (value << 4) + 10 + aChar - 'a';
                             break;
                         case 'A':
                         case 'B':
                         case 'C':
                         case 'D':
                         case 'E':
                         case 'F':
                             value = (value << 4) + 10 + aChar - 'A';
                             break;
                         default:
                             throw new IllegalArgumentException(
                                     "Malformed
\\uxxxx encoding.");
                         }
                     }
                     out[outLen++] = (char) value;
                 } else {
                     if (aChar == 't') {
                         aChar = '\t';
                     } else if (aChar == 'r') {
                         aChar = '\r';
                     } else if (aChar == 'n') {
                         aChar = '\n';
                     } else if (aChar == 'f') {
                         aChar = '\f';
                     }
                     out[outLen++] = aChar;
                 }
             } else {
                 out[outLen++] = (char) aChar;
             }
         }
         return new String(out, 0, outLen);
     }
}

最後更新:2017-04-02 06:52:15

  上一篇:go 中文轉換成Unicode編碼和Unicode編碼轉換成中文,Java代碼實現
  下一篇:go KeyWordHelper-關鍵字提取類(注:使用第三方組件DictSeg.dll)