使用 Java 将中文字符转换成 Unicode 编码

版权声明:转载时请务必保留以下作者信息和链接
作者:陈维(chenweionline@hotmail.com)作者的网站:http://www.chenwei.mobi

这两天操作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.java,若你在项目中使用请不要改变package及author等作者信息。

/**/ /*
*CharacterSetToolkit.java
*
*Createdon2007年5月17日,上午11:04
*
*Tochangethistemplate,chooseTools|TemplateManager
*andopenthetemplateintheeditor.
*/


package mobi.chenwei.wing.util;

/***/ /**
*进行字符操作的工具类。

*
@authorChenWei
*@websitewww.chenwei.mobi
*@emailchenweionline@hotmail.com
*/

public class CharacterSetToolkit ... {

/***//**CreatesanewinstanceofCharacterSetToolkit*/
publicCharacterSetToolkit()...{
}


privatestaticfinalchar[]hexDigit=...{
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
}
;

privatestaticchartoHex(intnibble)...{
returnhexDigit[(nibble&0xF)];
}


/***//**
*将字符串编码成Unicode。
*
@paramtheString待转换成Unicode编码的字符串。
*
@paramescapeSpace是否忽略空格。
*
@return返回转换后Unicode编码的字符串。
*/

publicstaticStringtoUnicode(StringtheString,booleanescapeSpace)...{
intlen=theString.length();
intbufLen=len*2;
if(bufLen<0)...{
bufLen
=Integer.MAX_VALUE;
}

StringBufferoutBuffer
=newStringBuffer(bufLen);

for(intx=0;x<len;x++)...{
charaChar=theString.charAt(x);
//Handlecommoncasefirst,selectinglargestblockthat
//avoidsthespecialsbelow
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' ':outBuffer.append('\');outBuffer.append('t');
break;
case' ':outBuffer.append('\');outBuffer.append('n');
break;
case' ':outBuffer.append('\');outBuffer.append('r');
break;
case' ':outBuffer.append('\');outBuffer.append('f');
break;
case'='://Fallthrough
case':'://Fallthrough
case'#'://Fallthrough
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);
}

}

}

returnoutBuffer.toString();
}


/***//**
*从Unicode码转换成编码前的特殊字符串。
*
@paraminUnicode编码的字符数组。
*
@paramoff转换的起始偏移量。
*
@paramlen转换的字符长度。
*
@paramconvtBuf转换的缓存字符数组。
*
@return完成转换,返回编码前的特殊字符串。
*/

publicStringfromUnicode(char[]in,intoff,intlen,char[]convtBuf)...{
if(convtBuf.length<len)...{
intnewLen=len*2;
if(newLen<0)...{
newLen
=Integer.MAX_VALUE;
}

convtBuf
=newchar[newLen];
}

charaChar;
char[]out=convtBuf;
intoutLen=0;
intend=off+len;

while(off<end)...{
aChar
=in[off++];
if(aChar=='\')...{
aChar
=in[off++];
if(aChar=='u')...{
//Readthexxxx
intvalue=0;
for(inti=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:
thrownewIllegalArgumentException(
"Malformed\uxxxxencoding.");
}

}

out[outLen
++]=(char)value;
}
else...{
if(aChar=='t')...{
aChar
=' ';
}
elseif(aChar=='r')...{
aChar
=' ';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值