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

简介:

繁简体(GB<=>Big5)中文字符的转化实现原理很简单,就是根据两种码表的编码规则,创建两者之间的字符对应关系表,通过程序读取这个映射表来自动查出另一种编码方式下对应字符的字节编码,从而进行逐字节的内容替换。 

主功能实现的GB2Big5.java源代码如下:
package zeal.util;


import java.io.*;


/**

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

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

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

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

 * <p>Description: Deal with the convertion between gb2312 and big5 charset Strings.</p>

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

 * <p>Company: NewmenBase</p>

 * @author Zeal Li

 * @version 1.0

 *

 * @see zeal.util.StreamConverter

 */


public class GB2Big5{

    private static GB2Big5 pInstance = null;

    private String s_big5TableFile = null;

    private String s_gbTableFile = null;

    private byte[] b_big5Table = null;

    private byte[] b_gbTable = null;


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

    private GB2Big5(String sgbTableFile,String sbig5TableFile) 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){

            throw new NullPointerException("No gb table can be load");

        }

        if(null == b_big5Table){

            throw new NullPointerException("No big5 table can be load");

        }

    }


    public static synchronized GB2Big5 getInstance(){

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

        return getInstance("/zeal/util/gb-big5.table",

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

    }


    public static synchronized GB2Big5 getInstance(String sgbTableFile,

    String sbig5TableFile){

        if(null == pInstance){

            try{

                pInstance = new GB2Big5(sgbTableFile,sbig5TableFile);

            }

            catch(Exception e){

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

                pInstance = null;

            }

        }


        return pInstance;

    }


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

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

    protected synchronized void resetBig5Char(String gbChar,String big5Char) throws

    Exception{

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

        byte[] TextBig5 = new String(big5Char.getBytes(),

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

        int max = Text.length - 1;

        int h = 0;

        int l = 0;

        int p = 0;

        int b = 256;

        byte[] big = new byte[2];

        for(int i = 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){

                    ; // do nothing

                }

                else{

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

                    b_gbTable[p] = TextBig5[i];

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

                }

                i++;

            }

        }


        BufferedOutputStream pWriter = new BufferedOutputStream(new

        FileOutputStream(s_gbTableFile));

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

        pWriter.close();

    }


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

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

    protected synchronized void resetGbChar(String big5Char,String gbChar) throws

    Exception{

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

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

        int max = Text.length - 1;

        int h = 0;

        int l = 0;

        int p = 0;

        int b = 256;

        byte[] big = new byte[2];

        for(int i = 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){

                    ; // do nothing

                }

                else{

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

                    b_big5Table[p] = TextGb[i];

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

                }

                i++;

            }

        }


        BufferedOutputStream pWriter = new BufferedOutputStream(new

        FileOutputStream(s_big5TableFile));

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

        pWriter.close();

    }


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

    public byte[] gb2big5(String inStr) throws Exception{

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

            return "".getBytes();

            //return "";

        }


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

        int max = Text.length - 1;

        int h = 0;

        int l = 0;

        int p = 0;

        int b = 256;

        byte[] big = new byte[2];

        for(int i = 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(Exception e){

                        big[0] = 45;

                    }

                    try{

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

                    }

                    catch(Exception e){

                        big[1] = 45;

                    }

                }

                Text[i] = big[0];

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

                i++;

            }


        }


        return Text;

        //return new String(Text);

    }


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

    public String big52gb(String inStr) throws Exception{

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

            return "";

        }


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

        int max = Text.length - 1;

        int h = 0;

        int l = 0;

        int p = 0;

        int b = 256;

        byte[] big = new byte[2];

        for(int i = 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(Exception e){

                        big[0] = 45;

                    }

                    try{

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

                    }

                    catch(Exception e){

                        big[1] = 45;

                    }

                }

                Text[i] = big[0];

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

                i++;

            }


        }


        return new String(Text);

    }


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

    private static byte[] getBytesFromFile(String inFileName){

        try{

            InputStream in = GB2Big5.class.getResourceAsStream(inFileName);

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

            in.close();

            return sContent;


            /*

             java.io.RandomAccessFile inStream = new java.io.RandomAccessFile(

                         inFileName,"r");

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

                         inStream.read(sContent);

                         inStream.close();

                         return sContent;

             */

        }

        catch(Exception e){

            e.printStackTrace();

            return null;

        }

    }


    public static void main(String[] args) throws Exception{

        if(args.length < 2){

            System.out.println(

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

            System.exit(1);

            return;

        }


        boolean bIsGB = true;

        String inStr = "";

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

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

                bIsGB = true;

            }

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

                bIsGB = false;

            }

            else{

                inStr = args[i];

            }

        }


        GB2Big5 pTmp = GB2Big5.getInstance();


        String outStr = "";

        if(bIsGB){

            outStr = pTmp.big52gb(inStr);

        }

        else{

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

        }


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

                           "]");

    }

}

 
使用示例:
如果下载发布形式的zip类库包,可以在命令行下输入
java -classpath GB2Big5.zip zeal.util.GB2Big5 -big5 中国
可以看到繁体转化的输出情况。
 
或者自己写一个测试的class如下:
import zeal.util.*;

public class MyTest{

    public static void main(String[] args) throws Exception{

        if(args.length < 2){

            System.out.println(

            "Usage: MyTest [-gb | -big5] inputstring");

            System.exit(1);

            return;

        }

        boolean bIsGB = true;

        String inStr = "";

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

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

                bIsGB = true;

            }

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

                bIsGB = false;

            }

            else{

                inStr = args[i];

            }

        }

        // 得到一个繁简体字符处理的实例

        GB2Big5 pTmp = GB2Big5.getInstance();

        String outStr = "";

        if(bIsGB){

            // 如果需要把big5码的字符转化成gb2312的,就使用big52gb()方法。

            // 传入字符串参数,传出的也是字符串。

            outStr = pTmp.big52gb(inStr);

        }

        else{

            // 如果需要把gb2312码的字符转化成big5的,就使用gb2big5()方法。

            // 传入的是字符串参数,传出的是字节数组(因为有可能需要把big5码的内容

            // 写入文件,就必须用字节数组的方式写入,否则经过字节->字符串的转化之后

            // 再写入文件就变成乱码了)。如果需要直接显示出来,就new一个BIG5的字符

            // 串就行了。

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

        }

        System.out.println( "String [" + inStr + "] converted into:\n[" + 

                            outStr +

                            "]");

    }

}

##############################
直接调用GB2Big5只适用于对于少量字符的转化,当需要对整个jsp页面根据用户需要进行编码转化
的时候,就需要使用到taglib的功能。
具体配置使用步骤如下:
1.在WEB-INF/目录下增加GB2Big5Wrapper.tld文件,内容如下:
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE taglib

   PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.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页面里面加上:
<%@ taglib uri="/WEB-INF/GB2Big5Wrapper.tld" prefix="zealLi"%>
<zealLi:GB2Big5Wrapper isbig5="true">
任何你需要转化的东西
</zealLi:GB2Big5Wrapper>
比如test.jsp源代码如下 => 
<%@ page

contentType="text/html; charset=GBK"

import="javax.servlet.http.HttpSession"

import="java.util.*"

import="com.zealLi.*"

%><%

String encode = request.getParameter("encode");

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

  encode = "BIG5";

}

boolean isBig5 = false;

String charset = "GB2312";

if(encode.equalsIgnoreCase("BIG5")){

  isBig5 = true;

  charset = "BIG5";

}

String sInfo = "中文字体繁简体转化的测试。";

%><%@ taglib uri="/WEB-INF/GB2Big5Wrapper.tld" prefix="zealLi"%>

<zealLi:GB2Big5Wrapper isbig5="<%= isBig5 %>">

<html>

  <head>

    <title>Jsp测试页面</title>

    <meta http-equiv="Content-Type" content="text/html; charset=<%=charset%>">

  </head>

  <body>

    <%

    Calendar now = 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,182 bytes): 发布形式的类库zip文件,可直接使用 发布形式的类库zip文件,可直接使用

附件 GB2Big5_Project.zip(38,685 bytes): JBuilder工程文件,提供完整的源代码 JBuilder工程文件,提供完整的源代码

From: http://www.cnblogs.com/hardrock/archive/2006/02/10/328315.html

分类: 4.其他技术区

相关文章
|
2天前
|
存储 安全 Java
Java零基础-字符串详解
【10月更文挑战第18天】Java零基础教学篇,手把手实践教学!
87 60
|
19天前
|
Java 数据库
案例一:去掉数据库某列中的所有英文,利用java正则表达式去做,核心:去掉字符串中的英文
这篇文章介绍了如何使用Java正则表达式从数据库某列中去除所有英文字符。
32 15
|
21天前
|
Java
JAVA易错点详解(数据类型转换、字符串与运算符)
JAVA易错点详解(数据类型转换、字符串与运算符)
43 4
|
2月前
|
Java 数据库
java小工具util系列1:日期和字符串转换工具
java小工具util系列1:日期和字符串转换工具
45 3
|
2月前
|
SQL Java 索引
java小工具util系列2:字符串工具
java小工具util系列2:字符串工具
14 2
|
2月前
|
存储 移动开发 Java
java核心之字符串与编码
java核心之字符串与编码
16 2
|
2月前
|
Java
Java实现:将带时区的时间字符串转换为LocalDateTime对象
通过上述方法,你可以将带时区的时间字符串准确地转换为 `LocalDateTime`对象,这对于处理不需要时区信息的日期和时间场景非常有用。
577 4
|
6月前
|
存储 XML 缓存
Java字符串内幕:String、StringBuffer和StringBuilder的奥秘
Java字符串内幕:String、StringBuffer和StringBuilder的奥秘
63 0
|
3月前
|
安全 Java API
【Java字符串操作秘籍】StringBuffer与StringBuilder的终极对决!
【8月更文挑战第25天】在Java中处理字符串时,经常需要修改字符串,但由于`String`对象的不可变性,频繁修改会导致内存浪费和性能下降。为此,Java提供了`StringBuffer`和`StringBuilder`两个类来操作可变字符串序列。`StringBuffer`是线程安全的,适用于多线程环境,但性能略低;`StringBuilder`非线程安全,但在单线程环境中性能更优。两者基本用法相似,通过`append`等方法构建和修改字符串。
54 1
|
3月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
112 0