您的位置:首页 > 编程语言 > Java开发

繁简体(GBBig5)字符串转化的JAVA方式实现

2006-02-10 14:00 465 查看
繁简体(GB<=>Big5)中文字符的转化实现原理很简单,就是根据两种码表的编码规则,创建两者之间的字符对应关系表,通过程序读取这个映射表来自动查出另一种编码方式下对应字符的字节编码,从而进行逐字节的内容替换。
主功能实现的GB2Big5.java源代码如下:
packagezeal.util;

importjava.io.*;

/**

*用来处理GB2312/BIG5码字符互相转换的类.

*需要两个码表文件:/zeal/util/gb-big5.table,/zeal/util/big5-gb.table.

*这两个码表可以根据具体情况补充映射不正确的码.

*<p>Title:GB<=>Big5</p>

*<p>Description:Dealwiththeconvertionbetweengb2312andbig5charsetStrings.</p>

*<p>Copyright:Copyright(c)2004</p>

*<p>Company:NewmenBase</p>

*@authorZealLi

*@version1.0

*

*@seezeal.util.StreamConverter

*/

publicclassGB2Big5{

privatestaticGB2Big5pInstance=null;

privateStrings_big5TableFile=null;

privateStrings_gbTableFile=null;

privatebyte[]b_big5Table=null;

privatebyte[]b_gbTable=null;

/**指定两个码表文件来进行初始化*/

privateGB2Big5(StringsgbTableFile,Stringsbig5TableFile)throws

NullPointerException{

s_big5TableFile=sbig5TableFile;

s_gbTableFile=sgbTableFile;

if(null==b_gbTable){

b_gbTable=getBytesFromFile(sgbTableFile);

}

if(null==b_big5Table){

b_big5Table=getBytesFromFile(sbig5TableFile);

}

if(null==b_gbTable){

thrownewNullPointerException("Nogbtablecanbeload");

}

if(null==b_big5Table){

thrownewNullPointerException("Nobig5tablecanbeload");

}

}

publicstaticsynchronizedGB2Big5getInstance(){

//returngetInstance("d:\\gb-big5.table","d:\\big5-gb.table");

returngetInstance("/zeal/util/gb-big5.table",

"/zeal/util/big5-gb.table");

}

publicstaticsynchronizedGB2Big5getInstance(StringsgbTableFile,

Stringsbig5TableFile){

if(null==pInstance){

try{

pInstance=newGB2Big5(sgbTableFile,sbig5TableFile);

}

catch(Exceptione){

System.err.println(e.toString());

pInstance=null;

}

}

returnpInstance;

}

/**把gbChar对应的big5字符替换掉,用来更新码表文件.

*一般当发现字符映射不正确的时候可以通过这个方法来校正.*/

protectedsynchronizedvoidresetBig5Char(StringgbChar,Stringbig5Char)throws

Exception{

byte[]Text=newString(gbChar.getBytes(),"GBK").getBytes("GBK");

byte[]TextBig5=newString(big5Char.getBytes(),

"BIG5").getBytes("BIG5");

intmax=Text.length-1;

inth=0;

intl=0;

intp=0;

intb=256;

byte[]big=newbyte[2];

for(inti=0;i<max;i++){

h=(int)(Text[i]);

if(h<0){

h=b+h;

l=(int)(Text[i+1]);

if(l<0){

l=b+(int)(Text[i+1]);

}

if(h==161&&l==64){

;//donothing

}

else{

p=(h-160)*510+(l-1)*2;

b_gbTable[p]=TextBig5[i];

b_gbTable[p+1]=TextBig5[i+1];

}

i++;

}

}

BufferedOutputStreampWriter=newBufferedOutputStream(new

FileOutputStream(s_gbTableFile));

pWriter.write(b_gbTable,0,b_gbTable.length);

pWriter.close();

}

/**把big5Char对应的gb字符替换掉,用来更新码表文件.

*一般当发现字符映射不正确的时候可以通过这个方法来校正.*/

protectedsynchronizedvoidresetGbChar(Stringbig5Char,StringgbChar)throws

Exception{

byte[]TextGb=newString(gbChar.getBytes(),"GBK").getBytes("GBK");

byte[]Text=newString(big5Char.getBytes(),"BIG5").getBytes("BIG5");

intmax=Text.length-1;

inth=0;

intl=0;

intp=0;

intb=256;

byte[]big=newbyte[2];

for(inti=0;i<max;i++){

h=(int)(Text[i]);

if(h<0){

h=b+h;

l=(int)(Text[i+1]);

if(l<0){

l=b+(int)(Text[i+1]);

}

if(h==161&&l==64){

;//donothing

}

else{

p=(h-160)*510+(l-1)*2;

b_big5Table[p]=TextGb[i];

b_big5Table[p+1]=TextGb[i+1];

}

i++;

}

}

BufferedOutputStreampWriter=newBufferedOutputStream(new

FileOutputStream(s_big5TableFile));

pWriter.write(b_big5Table,0,b_big5Table.length);

pWriter.close();

}

/**把gb2312编码的字符串转化成big5码的字节流*/

publicbyte[]gb2big5(StringinStr)throwsException{

if(null==inStr||inStr.length()<=0){

return"".getBytes();

//return"";

}

byte[]Text=newString(inStr.getBytes(),"GBK").getBytes("GBK");

intmax=Text.length-1;

inth=0;

intl=0;

intp=0;

intb=256;

byte[]big=newbyte[2];

for(inti=0;i<max;i++){

h=(int)(Text[i]);

if(h<0){

h=b+h;

l=(int)(Text[i+1]);

if(l<0){

l=b+(int)(Text[i+1]);

}

if(h==161&&l==64){

big[0]=big[1]=(byte)(161-b);

}

else{

p=(h-160)*510+(l-1)*2;

try{

big[0]=(byte)(b_gbTable[p]-b);

}

catch(Exceptione){

big[0]=45;

}

try{

big[1]=(byte)(b_gbTable[p+1]-b);

}

catch(Exceptione){

big[1]=45;

}

}

Text[i]=big[0];

Text[i+1]=big[1];

i++;

}

}

returnText;

//returnnewString(Text);

}

/**把big5码的字符串转化成gb2312码的字符串*/

publicStringbig52gb(StringinStr)throwsException{

if(null==inStr||inStr.length()<=0){

return"";

}

byte[]Text=newString(inStr.getBytes(),"BIG5").getBytes("BIG5");

intmax=Text.length-1;

inth=0;

intl=0;

intp=0;

intb=256;

byte[]big=newbyte[2];

for(inti=0;i<max;i++){

h=(int)(Text[i]);

if(h<0){

h=b+h;

l=(int)(Text[i+1]);

if(l<0){

l=b+(int)(Text[i+1]);

}

if(h==161&&l==161){

big[0]=(byte)(161-b);

big[1]=(byte)(64-b);

}

else{

p=(h-160)*510+(l-1)*2;

try{

big[0]=(byte)(b_big5Table[p]-b);

}

catch(Exceptione){

big[0]=45;

}

try{

big[1]=(byte)(b_big5Table[p+1]-b);

}

catch(Exceptione){

big[1]=45;

}

}

Text[i]=big[0];

Text[i+1]=big[1];

i++;

}

}

returnnewString(Text);

}

/**把文件读入字节数组,读取失败则返回null*/

privatestaticbyte[]getBytesFromFile(StringinFileName){

try{

InputStreamin=GB2Big5.class.getResourceAsStream(inFileName);

byte[]sContent=StreamConverter.toByteArray(in);

in.close();

returnsContent;

/*

java.io.RandomAccessFileinStream=newjava.io.RandomAccessFile(

inFileName,"r");

byte[]sContent=newbyte[(int)(inStream.length())];

inStream.read(sContent);

inStream.close();

returnsContent;

*/

}

catch(Exceptione){

e.printStackTrace();

returnnull;

}

}

publicstaticvoidmain(String[]args)throwsException{

if(args.length<2){

System.out.println(

"Usage:zeal.util.GB2Big5[-gb|-big5]inputstring");

System.exit(1);

return;

}

booleanbIsGB=true;

StringinStr="";

for(inti=0;i<args.length;i++){

if(args[i].equalsIgnoreCase("-gb")){

bIsGB=true;

}

elseif(args[i].equalsIgnoreCase("-big5")){

bIsGB=false;

}

else{

inStr=args[i];

}

}

GB2Big5pTmp=GB2Big5.getInstance();

StringoutStr="";

if(bIsGB){

outStr=pTmp.big52gb(inStr);

}

else{

outStr=newString(pTmp.gb2big5(inStr),"BIG5");

}

System.out.println("String["+inStr+"]convertedinto:\n["+outStr+

"]");

}

}
使用示例:
如果下载发布形式的zip类库包,可以在命令行下输入
java-classpathGB2Big5.zipzeal.util.GB2Big5-big5中国
可以看到繁体转化的输出情况。
或者自己写一个测试的class如下:
importzeal.util.*;publicclassMyTest{publicstaticvoidmain(String[]args)throwsException{if(args.length<2){System.out.println("Usage:MyTest[-gb|-big5]inputstring");System.exit(1);return;}booleanbIsGB=true;StringinStr="";for(inti=0;i<args.length;i++){if(args[i].equalsIgnoreCase("-gb")){bIsGB=true;}elseif(args[i].equalsIgnoreCase("-big5")){bIsGB=false;}else{inStr=args[i];}}//得到一个繁简体字符处理的实例GB2Big5pTmp=GB2Big5.getInstance();StringoutStr="";if(bIsGB){//如果需要把big5码的字符转化成gb2312的,就使用big52gb()方法。//传入字符串参数,传出的也是字符串。outStr=pTmp.big52gb(inStr);}else{//如果需要把gb2312码的字符转化成big5的,就使用gb2big5()方法。//传入的是字符串参数,传出的是字节数组(因为有可能需要把big5码的内容//写入文件,就必须用字节数组的方式写入,否则经过字节->字符串的转化之后//再写入文件就变成乱码了)。如果需要直接显示出来,就new一个BIG5的字符//串就行了。outStr=newString(pTmp.gb2big5(inStr),"BIG5");}System.out.println("String["+inStr+"]convertedinto:\n["+outStr+"]");}}
##############################
直接调用GB2Big5只适用于对于少量字符的转化,当需要对整个jsp页面根据用户需要进行编码转化
的时候,就需要使用到taglib的功能。
具体配置使用步骤如下:
1.在WEB-INF/目录下增加GB2Big5Wrapper.tld文件,内容如下:
<?xmlversion="1.0"encoding="ISO-8859-1"?><!DOCTYPEtaglibPUBLIC"-//SunMicrosystems,Inc.//DTDJSPTagLibrary1.2//EN""http://java.sun.om/dtd/web-jsptaglibrary_1_2.dtd"><taglib><tlib-version>1.0</tlib-version><jsp-version>1.2</jsp-version><short-name>zealLi</short-name><tag><name>GB2Big5Wrapper</name><tag-class>zeal.util.GB2Big5Wrapper</tag-class><attribute><name>isbig5</name><rtexprvalue>true</rtexprvalue><type>boolean</type></attribute></tag></taglib>2.在需要进行转化的JSP页面里面加上:
<%@tagliburi="/WEB-INF/GB2Big5Wrapper.tld"prefix="zealLi"%>
<zealLi:GB2Big5Wrapperisbig5="true">
任何你需要转化的东西
</zealLi:GB2Big5Wrapper>
比如test.jsp源代码如下=>
<%@pagecontentType="text/html;charset=GBK"import="javax.servlet.http.HttpSession"import="java.util.*"import="com.zealLi.*"%><%Stringencode=request.getParameter("encode");if(null==encode||encode.length()<=0){encode="BIG5";}booleanisBig5=false;Stringcharset="GB2312";if(encode.equalsIgnoreCase("BIG5")){isBig5=true;charset="BIG5";}StringsInfo="中文字体繁简体转化的测试。";%><%@tagliburi="/WEB-INF/GB2Big5Wrapper.tld"prefix="zealLi"%><zealLi:GB2Big5Wrapperisbig5="<%=isBig5%>"><html><head><title>Jsp测试页面</title><metahttp-equiv="Content-Type"content="text/html;charset=<%=charset%>"></head><body><%Calendarnow=Calendar.getInstance();out.println(now.get(Calendar.YEAR)+"."+(now.get(Calendar.MONTH)+1)+"."+now.get(Calendar.DAY_OF_MONTH)+"<p>");%><p><%=sInfo%></body></html></zealLi:GB2Big5Wrapper>

附件GB2Big5.zip(108,182bytes):

发布形式的类库zip文件,可直接使用附件GB2Big5_Project.zip(38,685bytes):

JBuilder工程文件,提供完整的源代码From:http://www.zeali.net/blog/entry.php?id=19
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: