精华内容
下载资源
问答
  • java中文问题详解

    2021-03-10 04:12:05
    Abstract:本文深入分析了Java程序设计中Java编译器对java源文件和JVM对class类文件的编码/解码过程,通过此过程的解析透视出了Java编程中中文问题产生的根本原因,最后给出了建议的最优化的解决Java中文问题的方法...

    Abstract:本文深入分析了Java程序设计中Java编译器对java源文件和JVM对class类文件的编码/解码过程,通过此过程的解析透视出了Java编程中中文问题产生的根本原因,最后给出了建议的最优化的解决Java中文问题的方法。

    1、中文问题的来源

    计算机最初的操作系统支持的编码是单字节的字符编码,于是,在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。随着计算机的发展,为了适应世界其它民族的语言(当然包括我们的汉字),人们提出了UNICODE编码,它采用双字节编码,兼容英文字符和其它民族的双字节字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此,我这里说的JDK是指国际版的JDK,我们大多数程序员使用的是国际化的JDK版本,以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言,为了能让计算机处理中文,我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。所以,大部分的操作系统为了适应我们处理中文的需求,均定制有中文操作系统,它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如:中文Win2K默认采用的是GBK编码显示,在中文WIN2k中保存文件时默认采用的保存文件的编码格式也是GBK的,即,所有在中文WIN2K中保存的文件它的内部编码默认均采用GBK编码,注意:GBK是在GB2312基础上扩充来的。

    由于Java语言内部采用UNICODE编码,所以在JAVA程序运行时,就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题,这个转换过程有着一系列的步骤,如果其中任何一步出错,则显示出来的汉字就会出是乱码,这就是我们常见的JAVA中文问题。

    同时,Java是一个跨平台的编程语言,也即我们编写的程序不仅能在中文windows上运行,也能在中文Linux等系统上运行,同时也要求能在英文等系统上运行(我们经常看到有人把在中文win2k上编写的JAVA程序,移植到英文Linux上运行)。这种移植操作也会带来中文问题。

    还有,有人使用英文的操作系统和英文的IE等浏览器,来运行带中文字符的程序和浏览中文网页,它们本身就不支持中文,也会带来中文问题。

    几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递,而不是按中文编码传递,所以,传递中文参数时也会有问题,从而带来乱码现象。

    总之,以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正确运行而产生的问题称作:JAVA中文问题。

    2、JAVA编码转换的详细过程

    我们常见的JAVA程序包括以下类别:

    *直接在console上运行的类(包括可视化界面的类)

    *JSP代码类(注:JSP是Servlets类的变型)

    *Servelets类

    *EJB类

    *其它不可以直接运行的支持类

    这些类文件中,都有可能含有中文字符串,并且我们常用前三类JAVA程序和用户直接交互,用于输出和输入字符,如:我们在JSP和Servlet中得到客户端送来的字符,这些字符也包括中文字符。无论这些JAVA类的作用如何,这些JAVA程序的生命周期都是这样的:

    *编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.java扩展名保存在操作系统中,例如我们在中文win2k中用记事本编辑一个java源程序;

    *编程人员用JDK中的javac.exe来编译这些源代码,形成.class类(JSP文件是由容器调用JDK来编译的);

    *直接运行这些类或将这些类布署到WEB容器中去运行,并输出结果。

    那么,在这些过程中,JDK和JVM是如何将这些文件如何编码和解码并运行的呢?

    这里,我们以中文win2k操作系统为例说明JAVA类是如何来编码和被解码的。

    第一步,我们在中文win2k中用编辑软件如记事本编写一个Java源程序文件(包括以上五类JAVA程序),程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.java文件,也即,java程序在被编译前,我们的JAVA源程序文件是采用操作系统默认支持的file.encoding编码格式保存的,java源程序中含有中文信息字符和英文程序代码;要查看系统的file.encoding参数,可以用以下代码:

    public class ShowSystemDefaultEncoding {

    public static void main(String[] args) {

    String encoding = System.getProperty("file.encoding");

    System.out.println(encoding);

    }}

    第二步,我们用JDK的javac.exe文件编译我们的Java源程序,由于JDK是国际版的,在编译的时候,如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式,则javac.exe首先获得我们操作系统默认采用的编码格式,也即在编译java程序时,若我们不指定源程序文件的编码格式,JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然后JDK就把我们的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。然后,javac把转换后的unicode格式的文件进行编译成.class类文件,此时.class文件是UNICODE编码的,它暂放在内存中,紧接着,JDK将此以UNICODE编码的编译后的class文件保存到我们的操作系统中形成我们见到的.class文件。对我们来说,我们最终获得的.class文件是内容以UNICODE编码格式保存的类文件,它内部包含我们源程序中的中文字符串,只不过此时它己经由file.encoding格式转化为UNICODE格式了。

    这一步中,对于JSP源程序文件是不同的,对于JSP,这个过程是这样的:即WEB容器调用JSP编译器,JSP编译器先查看JSP文件中是否设置有文件编码格式,如果JSP文件中没有设置JSP文件的编码格式,则JSP编译器调用JDK先把JSP文件用JVM默认的字符编码格式(也即WEB容器所在的操作系统的默认的file.encoding)转化为临时的Servlet类,然后再把它编译成UNICODE格式的class类,并保存在临时文件夹中。如:在中文win2k上,WEB容器就把JSP文件从GBK编码格式转化为UNICODE格式,然后编译成临时保存的Servlet类,以响应用户的请求。

    第三步,运行第二步编译出来的类,分为三种情况:

    A、 直接在console上运行的类

    B、 EJB类和不可以直接运行的支持类(如JavaBean类)

    C、 JSP代码和Servlet类

    D、 JAVA程序和数据库之间

    下面我们分这四种情况来看。

    A、直接在console上运行的类

    这种情况,运行该类首先需要JVM支持,即操作系统中必须安装有JRE。运行过程是这样的:首先java启动JVM,此时JVM读出操作系统中保存的class文件并把内容读入内存中,此时内存中为UNICODE格式的class类,然后JVM运行它,如果此时此类需要接收用户输入,则类会默认用file.encoding编码格式对用户输入的串进行编码并转化为unicode保存入内存(用户可以设置输入流的编码格式)。程序运行后,产生的字符串(UNICODE编码的)再回交给JVM,最后JRE把此字符串再转化为file.encoding格式(用户可以设置输出流的编码格式)传递给操作系统显示接口并输出到界面上。

    对于这种直接在console上运行的类,它的转化过程可用图1更加明确的表示出来:

    图1

    2005413105245225.gif

    以上每一步的转化都需要正确的编码格式转化,才能最终不出现乱码现象。

    B、EJB类和不可以直接运行的支持类(如JavaBean类)由于EJB类和不可以直接运行的支持类,它们一般不与用户直接交互输入和输出,它们常常与其它的类进行交互输入和输出,所以它们在第二步被编译后,就形成了内容是UNICODE编码的类保存在操作系统中了,以后只要它与其它的类之间的交互在参数传递过程中没有丢失,则它就会正确的运行。

    这种EJB类和不可以直接运行的支持类, 它的转化过程可用图2更加明确的表示出来:

    图2

    2005413105245372.gif

    C、JSP代码和Servlet类

    经过第二步后,JSP文件也被转化为Servlets类文件,只不过它不像标准的Servlets一校存在于classes目录中,它存在于WEB容器的临时目录中,故这一步中我们也把它做为Servlets来看。

    对于Servlets,客户端请求它时,WEB容器调用它的JVM来运行Servlet,首先,JVM把Servlet的class类从系统中读出并装入内存中,内存中是以UNICODE编码的Servlet类的代码,然后JVM在内存中运行该Servlet类,如果Servlet在运行的过程中,需要接受从客户端传来的字符如:表单输入的值和URL中传入的值,此时如果程序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859-1编码格式来接受传入的值并在JVM中转化为UNICODE格式的保存在WEB容器的内存中。Servlet运行后生成输出,输出的字符串是UNICODE格式的,紧接着,容器将Servlet运行产生的UNICODE格式的串(如html语法,用户输出的串等)直接发送到客户端浏览器上并输出给用户,如果此时指定了发送时输出的编码格式,则按指定的编码格式输出到浏览器上,如果没有指定,则默认按ISO-8859-1编码发送到客户的浏览器上。这种JSP代码和Servlet类,它的转化过程可用图3更加明确地表示出来:

    图3

    2005413105245793.gif

    D、Java程序和数据库之间

    对于几乎所有数据库的JDBC驱动程序,默认的在JAVA程序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的,所以,我们的程序在向数据库内存储包含中文的数据时,JDBC首先是把程序内部的UNICODE编码格式的数据转化为ISO-8859-1的格式,然后传递到数据库中,在数据库保存数据时,它默认即以ISO-8859-1保存,所以,这是为什么我们常常在数据库中读出的中文数据是乱码。

    对于JAVA程序和数据库之间的数据传递,我们可以用图4清晰地表示出来

    图4

    2005413105246999.gif

    3、分析常见的JAVA中文问题几个必须清楚的原则

    首先,经过上面的详细分析,我们可以清晰地看到,任何JAVA程序的生命期中,其编码转换的关键过程是在于:最初编译成class文件的转码和最终向用户输出的转码过程。

    其次,我们必须了解JAVA在编译时支持的、常用的编码格式有以下几种:

    *ISO-8859-1,8-bit, 同8859_1,ISO-8859-1,ISO_8859_1等编码

    *Cp1252,美国英语编码,同ANSI标准编码

    *UTF-8,同unicode编码

    *GB2312,同gb2312-80,gb2312-1980等编码

    *GBK , 同MS936,它是gb2312的扩充

    及其它的编码,如韩文、日文、繁体中文等。同时,我们要注意这些编码间的兼容关体系如下:

    unicode和UTF-8编码是一一对应的关系。GB2312可以认为是GBK的子集,即GBK编码是在gb2312上扩展来的。同时,GBK编码包含了20902个汉字,编码范围为:0x8140-0xfefe,所有的字符可以一一对应到UNICODE2.0中来。

    再次,对于放在操作系统中的.java源程序文件,在编译时,我们可以指定它内容的编码格式,具体来说用-encoding来指定。注意:如果源程序中含有中文字符,而你用-encoding指定为其它的编码字符,显然是要出错的。用-encoding指定源文件的编码方式为GBK或gb2312,无论我们在什么系统上编译含有中文字符的JAVA源程序都不会有问题,它都会正确地将中文转化为UNICODE存储在class文件中。

    然后,我们必须清楚,几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的,同时,几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以,虽然我们的Java源文件在出入口的地方指定了正确的编码方式,但其在容器内部运行时还是以ISO-8859-1来处理的。

    4、中文问题的分类及其建议最优解决办法

    了解以上JAVA处理文件的原理之后,我们就可以提出了一套建议最优的解决汉字问题的办法。

    我们的目标是:我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行,或拿到其它操作系统中编译后能正确运行,能正确地传递中文和英文参数,能正确地和数据库交流中英文字符串。

    我们的具体思路是:在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即可。

    具体解决办法如下:

    1、 针对直接在console上运行的类

    对于这种情况,我们建议在程序编写时,如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出,程序中应该采用字符流来处理输入和输出,具体来说,应用以下面向字符型节点流类型:

    对文件:FileReader,FileWrieter

    其字节型节点流类型为:FileInputStream,FileOutputStream

    对内存(数组):CharArrayReader,CharArrayWriter

    其字节型节点流类型为:ByteArrayInputStream,ByteArrayOutputStream

    对内存(字符串):StringReader,StringWriter

    对管道:PipedReader,PipedWriter

    其字节型节点流类型为:PipedInputStream,PipedOutputStream

    同时,应该用以下面向字符型处理流来处理输入和输出:

    BufferedWriter,BufferedReader

    其字节型的处理流为:BufferedInputeStream,BufferedOutputStream

    InputStreamReader,OutputStreamWriter

    其字节型的处理流为:DataInputStream,DataOutputStream

    其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流,如:

    InputStreamReader in = new InputStreamReader(System.in,"GB2312");

    OutputStreamWriter out = new OutputStreamWriter (System.out,"GB2312");

    例如:采用如下的示例JAVA编码就达到了要求:

    //Read.java

    import java.io.*;

    public class Read {

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

    String str = "\n中文测试,这是内部硬编码的串"+"\ntest english character";

    String strin= "";

    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //设置输入接口按中文编码

    BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //设置输出接口按中文编码

    stdout.write("请输入:");

    stdout.flush();

    strin = stdin.readLine();

    stdout.write("这是从用户输入的串:"+strin);

    stdout.write(str);

    stdout.flush();

    }}

    同时,在编译程序时,我们用以下方式来进行:

    javac -encoding gb2312 Read.java

    其运行结果如图5所示:

    200541311020722.gif

    图5

    2、 针对EJB类和不可以直接运行的支持类(如JavaBean类)

    由于这种类它们本身被其它的类调用,不直接与用户交互,故对这种类来说,我们的建议的处理方式是内部程序中应该采用字符流来处理程序内部的中文字符串(具体如上面一节中一样),同时,在编译类时用-encoding gb2312参数指示源文件是中文格式编码的即可。

    3、 针对Servlet类

    针对Servlet,我们建议用以下方法:

    在编译Servlet类的源程序时,用-encoding指定编码为GBK或GB2312,且在向用户输出时的编码部分用response对象的setContentType("text/html;charset=GBK");或gb2312来设置输出编码格式,同样在接收用户输入时,我们用request.setCharacterEncoding("GB2312");这样无论我们的servlet类移植到什么操作系统中,只有客户端的浏览器支持中文显示,就可以正确显示。如下是一个正确的示例:

    //HelloWorld.java

    package hello;

    import java.io.*;

    import javax.servlet.*;

    import javax.servlet.http.*;

    public class HelloWorld extends HttpServlet

    {

    public void init() throws ServletException { }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

    {

    request.setCharacterEncoding("GB2312"); //设置输入编码格式

    response.setContentType("text/html;charset=GB2312"); //设置输出编码格式

    PrintWriter out = response.getWriter(); //建议使用PrintWriter输出

    out.println("


    ");

    out.println("Hello World! This is created by Servlet!测试中文!");

    out.println("


    ");

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

    {

    request.setCharacterEncoding("GB2312"); //设置输入编码格式

    response.setContentType("text/html;charset=GB2312"); //设置输出编码格式

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

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

    if(name==null) name="";

    if(id==null) id="";

    PrintWriter out = response.getWriter(); //建议使用PrintWriter输出

    out.println("


    ");

    out.println("你传入的中文字串是:" + name);

    out.println("


    你输入的id是:" + id);

    out.println("


    ");

    }

    public void destroy() { }

    }

    请用javac -encoding gb2312 HelloWorld.java来编译此程序。

    测试此Servlet的程序如下所示:

    function Submit() {

    //通过URL传递中文字符串值给Servlet

    document.base.action = "./HelloWorld?name=中文";

    document.base.method = "POST";

    document.base.submit();

    }

    传给Servlet

    其运行结果如图6所示:

    200541311020140.gif

    图6

    4、 JAVA程序和数据库之间

    为避免JAVA程序和数据库之间数据传递出现乱码现象,我们建议采用以下最优方法来处理:

    1、 对于JAVA程序的处理方法按我们指定的方法处理。

    2、 把数据库默认支持的编码格式改为GBK或GB2312的。

    如:在mysql中,我们可以在配置文件my.ini中加入以下语句实现:

    在[mysqld]区增加:

    default-character-set=gbk

    并增加:

    [client]

    default-character-set=gbk

    在SQL Server2K中,我们可以将数据库默认的语言设置为Simplified Chinese来达到目的。

    5、 针对JSP代码

    由于JSP是在运行时,由WEB容器进行动态编译的,如果我们没有指定JSP源文件的编码格式,则JSP编译器会获得服务器操作系统的file.encoding值来对JSP文件编译的,它在移植时最容易出问题,如在中文win2k中可以很好运行的jsp文件拿到英文linux中就不行,尽管客户端都是一样的,那是因为容器在编译JSP文件时获取的操作系统的编码不同造成的(在中文wink中的file.encoding和在英文Linux中file.encoding是不同的,且英文Linux的file.encoding对中文不支持,所以编译出来的JSP类就会有问题)。网络上讨论的大多数是此类问题,多是因为JSP文件移植平台时不能正确显示的问题,对于这类问题,我们了解了JAVA中程序编码转换的原理,解决起来就容易多了。我们建议的解决办法如下:

    1、我们要保证JSP向客户端输出时是采用中文编码方式输出的,即无论如何我们首先在我们的JSP源代编中加入以下一行:

    2、为了让JSP能正确获得传入的参数,我们在JSP源文件头加入下面一句:

    3、为了让JSP编译器能正确地解码我们的含有中文字符的JSP文件,我们需要在JSP源文件中指定我们的JSP源文件的编码格式,具体来说,我们在JSP源文件头上加入下面的一句即可:

    这是JSP规范2.0新增加的指令。

    我们建议使用此方法来解JSP文件中的中文问题,下面的代码是一个正确做法的JSP文件的测试程序:

    //testchinese.jsp

    String action = request.getParameter("ACTION");

    String name = "";

    String str = "";

    if(action!=null && action.equals("SENT"))

    {

    name = request.getParameter("name");

    str = request.getParameter("str");

    }

    %>

    function Submit()

    {

    document.base.action = "?ACTION=SENT&str=传入的中文";

    document.base.method = "POST";

    document.base.submit();

    }

    提交

    if(action!=null && action.equals("SENT"))

    {

    out.println("
    你输入的字符为:"+name);

    out.println("
    你通过URL传入的字符为:"+str);

    }

    %>

    如图7是此程序运行的结果示意图:

    200541311020506.gif

    图7

    5、总结

    在上面的详细分析中,我们清晰地给出了JAVA在处理源程序过程中的详细转换过程,为我们正确解决JAVA编程中的中文问题提供了基础。同时,我们给出了认为是最优的解决JAVA中文问题的办法。

    展开全文
  • 由于Java编程中的中文问题是一个老生常谈的问题,在阅读了许多关于Java中文问题解决方法之后,结合作者的编程实践,我发现过去谈的许多方法都不能清晰地说明问题及解决问题,尤其是跨平台时的中文问题。于是我给出此篇...

    深入Java中文问题及最优解决方法

    说明:本文为作者原创,作者联系地址为:josserchai@yahoo.com。由于Java编程中的中文问题是一个老生常谈的问题,在阅读了许多关于Java中文问题解决方法之后,结合作者的编程实践,我发现过去谈的许多方法都不能清晰地说明问题及解决问题,尤其是跨平台时的中文问题。于是我给出此篇文章,内容包括对控制台运行的class、Servelets、JSP及EJB类中的中文问题我剖析和建议解决办法。希望大家指教。

    Abstract:本文深入分析了Java程序设计中Java编译器对java源文件和JVM对class类文件的编码/解码过程,通过此过程的解析透视出了Java编程中中文问题产生的根本原因,最后给出了建议的最优化的解决Java中文问题的方法。

    中文问题的来源

    计算机最初的操作系统支持的编码是单字节的字符编码,于是,在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。随着计算机的发展,为了适应世界其它民族的语言(当然包括我们的汉字),人们提出了UNICODE编码,它采用双字节编码,兼容英文字符和其它民族的双字节字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此,我这里说的JDK是指国际版的JDK,我们大多数程序员使用的是国际化的JDK版本,以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言,为了能让计算机处理中文,我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。所以,大部分的操作系统为了适应我们处理中文的需求,均定制有中文操作系统,它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如:中文Win2K默认采用的是GBK编码显示,在中文WIN2k中保存文件时默认采用的保存文件的编码格式也是GBK的,即,所有在中文WIN2K中保存的文件它的内部编码默认均采用GBK编码,注意:GBK是在GB2312基础上扩充来的。

    由于Java语言内部采用UNICODE编码,所以在JAVA程序运行时,就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题,这个转换过程有着一系列的步骤,如果其中任何一步出错,则显示出来的汉字就会出是乱码,这就是我们常见的JAVA中文问题。

    同时,Java是一个跨平台的编程语言,也即我们编写的程序不仅能在中文windows上运行,也能在中文Linux等系统上运行,同时也要求能在英文等系统上运行(我们经常看到有人把在中文win2k上编写的JAVA程序,移植到英文Linux上运行)。这种移植操作也会带来中文问题。

    还有,有人使用英文的操作系统和英文的IE等浏览器,来运行带中文字符的程序和浏览中文网页,它们本身就不支持中文,也会带来中文问题。

    几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递,而不是按中文编码传递,所以,传递中文参数时也会有问题,从而带来乱码现象。

    总之,以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正确运行而产生的问题称作:JAVA中文问题。

    JAVA编码转换的详细过程

    我们常见的JAVA程序包括以下类别:直接在console上运行的类(包括可视化界面的类)

    JSP代码类(注:JSP是Servlets类的变型)

    Servelets类

    EJB类

    其它不可以直接运行的支持类

    这些类文件中,都有可能含有中文字符串,并且我们常用前三类JAVA程序和用户直接交互,用于输出和输入字符,如:我们在JSP和Servlet中得到客户端送来的字符,这些字符也包括中文字符。无论这些JAVA类的作用如何,这些JAVA程序的生命周期都是这样的:

    编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.java扩展名保存在操作系统中,例如我们在中文win2k中用记事本编辑一个java源程序;

    编程人员用JDK中的javac.exe来编译这些源代码,形成.class类(JSP文件是由容器调用JDK来编译的);

    直接运行这些类或将这些类布署到WEB容器中去运行,并输出结果。

    那么,在这些过程中,JDK和JVM是如何将这些文件如何编码和解码并运行的呢?

    中文问题的分类及其建议最优解决办法

    了解以上JAVA处理文件的原理之后,我们就可以提出了一套建议最优的解决汉字问题的办法。 我们的目标是:我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行,或拿到其它操作系统中编译后能正确运行,能正确地传递中文和英文参数,能正确地和数据库交流中英文字符串。 我们的具体思路是:在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即可。

    具体解决办法如下:    1、 针对直接在console上运行的类    对于这种情况,我们建议在程序编写时,如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出,程序中应该采用字符流来处理输入和输出,具体来说,应用以下面向字符型节点流类型:对文件:FileReader,FileWrieter其字节型节点流类型为:FileInputStream,FileOutputStream 对内存(数组):CharArrayReader,CharArrayWriter其字节型节点流类型为:ByteArrayInputStream,ByteArrayOutputStream对内存(字符串):StringReader,StringWriter对管道:PipedReader,PipedWriter其字节型节点流类型为:PipedInputStream,PipedOutputStream同时,应该用以下面向字符型处理流来处理输入和输出:BufferedWriter,BufferedReader其字节型的处理流为:BufferedInputeStream,BufferedOutputStream InputStreamReader,OutputStreamWriter 其字节型的处理流为:DataInputStream,DataOutputStream其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流,如:InputStreamReader in = new InputStreamReader(System.in,"GB2312");OutputStreamWriter out = new OutputStreamWriter (System.out,"GB2312");例如:采用如下的示例JAVA编码就达到了要求:

    //Read.javaimport java.io.*;public class Read { public static void main(String[] args) throws IOException {  String str = "\n中文测试,这是内部硬编码的串"+"\ntest english character";  String strin= "";  BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //设置输入接口按中文编码  BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //设置输出接口按中文编码  stdout.write("请输入:");  stdout.flush();  strin = stdin.readLine();  stdout.write("这是从用户输入的串:"+strin);  stdout.write(str);  stdout.flush(); }}

    同时,在编译程序时,我们用以下方式来进行:    javac -encoding gb2312 Read.java

    展开全文
  • Java中文排序

    2021-02-28 15:58:53
    所谓中文排序就是按照汉语拼音的顺序进行排序,在Java中进行排序其实不需要自己来写算法,java.util.Arrays类中提供的sort方法可以直接实现这个功能。具体举个例子来说明。import java.util.*;import java.text.*;...

    所谓中文排序就是按照汉语拼音的顺序进行排序,在Java中进行排序其实不需要自己来写算法,java.util.Arrays类中提供的sort方法可以直接实现这个功能。

    具体举个例子来说明。

    import java.util.*;

    import java.text.*;

    public class SortByChinese {

    public static void main(String[] args) {

    // Collator 类是用来执行区分语言环境的 String 比较的,这里选择使用CHINA

    Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);

    String[] arr = {"张三", "李四", "王五", "刘六"};

    // 使根据指定比较器产生的顺序对指定对象数组进行排序。

    Arrays.sort(arr, cmp);

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

    System.out.println(arr[i]);

    System.out.println();

    }

    }

    展开全文
  • java汉字获取首字母

    2021-02-12 14:31:10
    9 10 /** 11 * 获取首字母工具12 *13 *@author 14 * @Date15 */ 16 public classChineseCharacterUtil {17 18 /** 19 * 获取汉字首字母或全拼大写字母20 *21 *@paramchinese 汉字22 *@paramisFull 是否全拼 true:...

    1 packageorg.jeecg.modules.system.util;2

    3 importnet.sourceforge.pinyin4j.PinyinHelper;4 importnet.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;5 importnet.sourceforge.pinyin4j.format.HanyuPinyinToneType;6

    7 importjava.util.regex.Matcher;8 importjava.util.regex.Pattern;9

    10 /**

    11 * 获取首字母工具12 *13 *@author

    14 * @Date15 */

    16 public classChineseCharacterUtil {17

    18 /**

    19 * 获取汉字首字母或全拼大写字母20 *21 *@paramchinese 汉字22 *@paramisFull 是否全拼 true:表示全拼 false表示:首字母23 *24 *@return全拼或者首字母大写字符窜25 */

    26 public static String getUpperCase(String chinese,booleanisFull){27 returnconvertHanzi2Pinyin(chinese,isFull).toUpperCase();28 }29

    30 /**

    31 * 获取汉字首字母或全拼小写字母32 *33 *@paramchinese 汉字34 *@paramisFull 是否全拼 true:表示全拼 false表示:首字母35 *36 *@return全拼或者首字母小写字符窜37 */

    38 public static String getLowerCase(String chinese,booleanisFull){39 returnconvertHanzi2Pinyin(chinese,isFull).toLowerCase();40 }41

    42 /**

    43 * 将汉字转成拼音44 *

    45 * 取首字母或全拼46 *47 *@paramhanzi 汉字字符串48 *@paramisFull 是否全拼 true:表示全拼 false表示:首字母49 *50 *@return拼音51 */

    52 private static String convertHanzi2Pinyin(String hanzi,booleanisFull){53 /***54 * ^[\u2E80-\u9FFF]+$ 匹配所有东亚区的语言55 * ^[\u4E00-\u9FFF]+$ 匹配简体和繁体56 * ^[\u4E00-\u9FA5]+$ 匹配简体57 */

    58 String regExp="^[\u4E00-\u9FFF]+$";59 StringBuffer sb=newStringBuffer();60 if(hanzi==null||"".equals(hanzi.trim())){61 return "";62 }63 String pinyin="";64 for(int i=0;i

    67 if(match(String.valueOf(unit),regExp)){68 pinyin=convertSingleHanzi2Pinyin(unit);69 if(isFull){70 sb.append(pinyin);71 }72 else{73 sb.append(pinyin.charAt(0));74 }75 }else{76 sb.append(unit);77 }78 }79 returnsb.toString();80 }81

    82 /**

    83 * 将单个汉字转成拼音84 *85 *@paramhanzi 汉字字符86 *87 *@return拼音88 */

    89 private static String convertSingleHanzi2Pinyin(charhanzi){90 HanyuPinyinOutputFormat outputFormat = newHanyuPinyinOutputFormat();91 outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);92 String[] res;93 StringBuffer sb=newStringBuffer();94 try{95 res =PinyinHelper.toHanyuPinyinStringArray(hanzi,outputFormat);96 sb.append(res[0]);//对于多音字,只用第一个拼音

    97 } catch(Exception e) {98 e.printStackTrace();99 return "";100 }101 returnsb.toString();102 }103

    104 /***105 * 匹配106 *

    107 * 根据字符和正则表达式进行匹配108 *109 *@paramstr 源字符串110 *@paramregex 正则表达式111 *112 *@returntrue:匹配成功 false:匹配失败113 */

    114 private static booleanmatch(String str,String regex){115 Pattern pattern=Pattern.compile(regex);116 Matcher matcher=pattern.matcher(str);117 returnmatcher.find();118 }119

    120 /**

    121 * 测试方法122 */

    123 public static voidmain(String[] args) {124 System.out.println(convertHanzi2Pinyin("弗格森的广东省q",false).toLowerCase());125 }126 }

    展开全文
  • java 汉字转化为全拼

    2021-02-13 02:06:05
    } /** * 获取汉语字符串的声母组合,每个汉字取拼音的第一个字符组成的一个字符串 * @param cnStr 汉字的字符串 * @return 每个汉字拼音的第一个字母所组成的汉字 */ public static String getFirstSpell(String ...
  • java 中文命名

    2021-02-27 11:39:09
    }加了之后也是一样的效果,还是nullhttp://mybatis.org/spring/zh/sample.html上面那个是中文文档说明,并且该连接有官网实例,建议通过该实例进行学习。先将官网实例跑通,再自行搭建环境 System.out.println(new ...
  • java中文转拼音

    2021-03-05 16:27:51
    在开发中,应该有人碰到过通过拼音查询的情况,特别是根据姓名查询时,方法有很多种,1、sql查询时处理,2、将中文转成拼音后再处理。等等....下面给大家介绍第二种,个人认为比较简单。import ...
  • Java中文乱码问题

    2021-02-28 15:59:20
    一、MyEclipse 下的java文件中文乱码问题(MyEclipse6.5):解决方法一:Window--àPreferences… --àGeneral --àContent Types --àText --àJava Source File 中Default encoding 改写成UTF-8(你所需的编码类型) ...
  • java中文转码解码

    2021-02-12 14:21:14
    在web.xml中配置该类的servlet信息和初始化信息 GET方式访问URL时参数的编解码工作:编码/传输/解码 基本过程: public static void main(String args[]){ String tsptString=”中文”; //1.编码(浏览器会按网页的编码...
  • private static final Map chineseMap = new HashMap();private static final String yearReg="[一|二|三|四|五|六|七|八|九|十|〇|○]{4}年";private static final String monthReg="(([十][一|二])|([一|二|三|四|...
  • java 中文 乱码 问号

    千次阅读 2021-02-13 02:20:51
    转自:http://blog.csdn.net/frank520/article/details/6865001java乱码的原因,原理,解决方法.String odsStr = "测试";...最近在编写Java程序的时候,偶尔会遇到中文字乱码的问题,或者偏僻字不能正常显示的...
  • java中文转byte数组

    2021-02-28 10:29:34
    String s="中国";byte[] buf=new byte[s.length()+1];//buf长度为3s.getBytes(0,s.length(),buf,0);//buf[0]=45,buf[1]=-3,buf[2]=0String sByte="";for(int i=0;isByte=sByte+String.format("%02X",buf[i])+" ";...
  • //这个是让中文数字变成可比较的值 arg0 = arg0.replaceAll("一", "11")); arg0 = arg0.replaceAll("二", "22"); arg0 = arg0.replaceAll("三", "33"); arg0 = arg0.replaceAll("四", "44"); arg0 = arg0.replaceAll...
  • java中文乱码解决总结

    千次阅读 2021-02-25 20:14:38
    这个首先要从编码机制上说起,大家都是中文和英文的编码格式不是一样,解码也是不一样的!如果中国的程序员不会遇到乱码,那么只有使用汉语编程。汉语编程是怎么回事我也不大清楚,应该是前年吧,我一朋友给我介绍...
  • java中文乱码怎么转换

    2021-03-06 21:20:26
    java中文乱码的转换方法:首先用编辑器编写java源文件;然后使用【javac.exe】编译java文件,并使用JDK将编译好的且保存在内存中信息写入class文件中;最后运行编译类。java中文乱码的转换方法:使用编码转换java...
  • java 中文与unicode互转

    2021-02-28 15:59:50
    public class YxqTest {public static void main(String[] args){// unicode 打印String title="\u4F60\u597D";...// 中文-转-unicodeString str = "你好";System.out.println(cnToUnicode(str));/...
  • 在基于Java的编程中,经常会碰到汉字的处里及显示的问题,比如一大堆乱码或问号。这是因为JAVA中默认的编码方式是UNICODE,而中国人通常使用的文件和DB都是基于GB2312或者BIG5等编码,故会出现此问题。1、在网页中...
  • Java中文转换为英文拼音import net.sourceforge.pinyin4j.PinyinHelper;import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;import ...
  • java汉字乱码解决办法

    千次阅读 2021-02-12 16:30:27
    一、Java中文问题的由来Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他...
  • 6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象...
  • 以下实例演示了如何使用 Calendar 类来输出年份、月份等: /*author by dba.cn文件名:Main.java*/import java.util.Calendar;public class Main {public static void main(String[] args) {Calendar cal = Calendar...
  • 贴出代码,方便学习交流,稍后放出镜像问题的代码package com.thunisoft.cail.utils;...import java.security.InvalidParameterException;import java.util.*;import java.util.regex.Matcher;import j...
  • java 中文转GBK码

    2021-02-12 12:29:35
    遇到一个需求,一个接口的调用时,需要将中文转成对应的GBK码,然后发请求调用,大概搜了下,貌似没有简单可行的现成方法,不像python能够直接decode / encode。找的时候有一个帖子给了启示: java默认用Unicode存储...
  • Java汉字处理

    2021-02-13 00:17:37
    输出结果: d6d0 说明:java内部使用的是unicode编码,汉字的Unicode编码范围为/u4E00-/u9FA5 或/uF900-/uFA2D,如果不在这个范围内就不是汉字。我们用char定义一个变量,如char ch="中"; 这时,ch是Unicode编码的...
  • LZ很想像其他大牛一样,书写自己的博客,但是怎奈何才疏学浅,...中文和Unicode码 互相转换package test.com.gjob.services;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java....
  • java中的中文乱码问题应该是我们经常碰到的一个问题,今天就来总结下对于乱码问题的解决方法:1. 超链接中带有的中文字符,添加这样如果不进行处理在后台得到的数据就会出现中文乱码的问题,由于超链接实际是用get...
  • 1、中文转成拼音首字母,返回值 ["拼音首字母","拼音全拼"]publicstaticString[]converterToSpellArray(Stringchines){if(chines==null||"".equals(chines)){returnnewString[]{"",""};}chines=...
  • 一、乱码的原因gbk的中文编码是一个汉字用【2】个字节表示,例如汉字“内部”的gbk编码16进制的显示为c4 da b2 bfutf-8的中文编码是一个汉字用【3】个字节表示,例如汉字“内部”的utf-8编码16进制的显示为e5 86 85 ...
  • 对于这样的情况,我有个建议你可以单独建立一个表用来索引汉字,比如createtableindex_char_Chinese(charIndexintprimarykey,charChinesenotnullunique);insertintoindex_char_Chinesevalues(0,'零');...
  • package com.sun;public class Snippet {public static void main(String[] args) {String cn = "你";...// 字符串 : \u5f00\u59cb\u4efb\u52a1 ,由于 \ 在java里是转义字符,要写出下面这种形式String un...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 675,300
精华内容 270,120
关键字:

java中文

java 订阅