java中文与unicode互转

来源:互联网 发布:listview.java 1594 编辑:程序博客网 时间:2024/06/03 17:38
这两天操作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);     }}





原创粉丝点击