`

Java程序中遇到的乱码问题以及解决方法

阅读更多

最近在编写Java程序的时候,偶尔会遇到中文字乱码的问题,或者偏僻字不能正常显示的问题,经过查找资料并通过几次测试,目前已经完全解决。
 
首先需要说明一下我们经常用到的字符集,有ISO8859-1,GB2312,GBK,GB18030,UNICODE。这里ISO8859-1字符集只包含英文字符,使用一个字节存储。GB2312、GBK和GB18030字符集包含中文字符,他们都兼容ISO8859-1字符集,他们的字符存储格式是变长的,其中GB18030包含GBK,GBK包含GB2312。UNICODE包含世界上所有国家的字符,UNICODE又分为UTF-8,UTF-16和UTF-32三种,UTF-8是变长字符集,它兼容ISO8859-1,即英文字符使用一个字节编码,而其他的字符使用2到4个字节编码,其中中文字符大部分都是使用3个字节进行编码,少量偏僻字使用4个字节编码,UTF-16统一都使用2个字节编码,它不兼容ISO8859-1,英文字符也使用两个字节,UTF-32统一使用4个字节编码,也不兼容ISO8859-1,可见UTF-16和UTF-32都比较浪费空间。
 
乱码问题的产生最根本的原因就是使用错误的字符集解码字节流或者将给定的字符串用错误的字符集编码成错误字节流造成的,例如”中文”两个汉字,如果用ISO8859-1字符集将其编码为字节流,因为这个字符集不支持中文,所以就会出错,输出结果为3f3f,其意义就是??。再例如”中文”二字的GBK的字节流为d6 d0 ce c4,可是我们要是用不兼容的字符集去解码,例如用ISO8859-1或者UTF-8,这随后产生的字符串就是乱码,或者是其他的某个字符。
 
从开发Java程序到运行Java程序的过程中都存在着编码问题,所以要想避免乱码产生,就必须了解在其中任何时候的编码处理的情况。
 
源代码:在编写java源代码的时候,我们必须把编写的文本保存在文件中,这个时候不管用什么编辑器,都存在一个问题,就是以什么样的字符集将这些源代码(包含汉字)保存到文件中,大部分编辑器都会通过系统的环境变量得到系统的当前默认字符集,编辑器就会使用这个字符集将我们编写的源代码保存到文件中。一般我们的中文Windows系统的默认字符集是GB18030,AIX英文环境的默认字符集是ISO8859-1,AIX中文环境的默认字符集是IBM-eucCN。
 
编译:在编译.java文件的时候如果使用默认处理,则javac会使用系统当前的默认字符集去读取源文件,将源文件的内容转换为UTF-8编码,然后在进行编译,这时我们也可以通过-encoding参数指定一个字符集,让javac使用我们指定的字符集去读取源代码,然后编译。编译以后产生的class文件内部所有的中文字符都是用UTF-8的字符集进行编码的,这就是Java程序能处理任何国家文字的原因。
 
运行时:Java程序在运行时,需要使用程序内部定义的中文字符串,也可能会使用从外部读取的中文字符串,这些经过处理,可能都会输出到程序外部,在这些过程中都涉及到编码的转换,程序内部定义的字符串都是用UTF-8存储的。而从外部读取和输出到程序外部的输出又使用什么字符集进行处理呢?在我们没有在程序中特别指定的情况下,JVM会根据系统属性确定使用哪个字符集,这个系统属性的名称为file.encoding,我们可以在启动java程序的时候通过-D参数设定这个值,如果没有设定,JVM会根据系统环境变量确定这个系统属性,一般我们的中文Windows系统的默认字符集是GB18030,AIX英文环境的默认字符集是ISO8859-1,AIX中文环境的默认字符集是IBM-eucCN。这样JVM在处理输入数据的时候就会把字节流根据这个参数进行解码,然后转成UTF-8格式,在Java程序内部处理,然后再根据这个参数把处理后的数据编码,输出到程序外部。这就是Java程序运行时字符集的使用情况。
 
现在有一个问题,我们平时都是Windows的中文环境下做开发,然后拿到AIX系统上去运行,AIX系统的默认语言环境是英文环境,这样就会出现乱码,分析过程如下:源文件编码格式为GB18030,默认编译,也采用GB18030读取源文件,正常转换为UTF-8,生成class文件,运行时没有进行特殊设置,语言环境为英文环境,默认编码为ISO8859-1,这样在输出中文的时候会把正常的UTF-8表示的汉字用ISO8859-1的字符集去编码生成字节流,因为ISO8859-1不支持汉字,结果输出的都是’?’。可是这个时候却发现,由外界输入给java程序的中文字符,却能正常输出,这又是为什么,其实这个也是运行时的默认字符集ISO8859-1造成的,Java程序运行时,在读取外部进入的字节流的时候,如果使用默认的读取方式,也是使用ISO8859-1的字符集进行解码处理,这样中间的处理过程中中文都已经不是原来的中文了,也就是说我们这个时候处理根本是我们认为的中文,而是一对乱码,虽然是乱码,但是其中的信息却没有丢失,在处理完后,在经过一次ISO8859-1的编码,又还原为正常的GB18030的编码输出,所有没有出现乱码。我们以前的解决方法是,在编译原文件的时候指定参数-encoding ISO8859-1,让编译器用ISO8859-1的字符集去解码源文件编译,然后运行程序,这时再输出程序的内部中文字符串也不是乱码了。看起来一切都解决了,可是却没有从根本上解决问题,class文件变得比平常大很多,程序中用到中文越多,class文件变大的越快。而且其中的中文信息也变味了。
 
另一个问题,如果我们正常编译程序,在AIX系统上线设定为中文环境,然后再运行Java程序,这样既不会使程序变大,也不会使中文变味,可是用了一段时间又发现问题了,处理过程中如果遇到偏僻的中文字,还是乱码,原因是AIX的中文环境使用的字符集是IBM-eucCN,我认为可能是这个字符集缺少偏僻汉字,无法解释其内容,所以偏僻字变成了乱码了。
 
最后的解决办法是,在Windows中文环境下正常编写原程序,用默认的方式编译生成class文件,或者编译时指定参数-encoding GB18030,这样汉字都能正常解释并转换为UTF-8存储在class文件中,在运行的时候,我们需要制定参数,java –Dfile.encoding=GB18030 。。。。。,系统环境使用默认英文即可,这样JVM就不会根据系统的环境设定默认字符集,而是所有输入输出都使用我们指定的字符集,这样不但解决了英文环境下的中文输出问题,而且还解决了偏僻字的显示问题。
 
最后附上汉字的转码过程:
1.‘中文’的GB18030编码为d6 d0 ce c4  对应java源码文件
经过ISO8859-1解码为UTF-8为81 30 89 30 81 30 88 34 81 30 88 32 81 30 87 32 对应编译过程
经过ISO8859-1编码为d6 d0 ce c4 对应Java程序输出汉字的过程
d6 d0 ce c4经GB18030解释为‘中文’二字 对应系统显示汉字的过程。
在这个过程中,虽然中间出现了乱码,但是信息没有丢,最后还是能还原为中文的,是比较蹩脚的处理过程。
 
2. ‘中文’二字的UTF-8编码为e4 b8 ad e6 96 87,对应正常编译后的class文件存储内容
经过ISO8859-1编码为3f 3f,已经出错,丢失信息,对应java程序汉字输出过程
3f 3f经GB18030解释为汉字为??,乱码,无法还原, 对应系统显示汉字的过程
这个过程中,信息丢失,是个完全错误的处理过程。
 
3. ‘中文’的GB18030编码为d6 d0 ce c4  对应java源码文件
经过GB18030解码为UTF-8为e4 b8 ad e6 96 87 对应编译过程
经过GB18030编码为d6 d0 ce c4 对应Java程序输出汉字的过长
d6 d0 ce c4经GB18030解释为‘中文’二字 对应系统显示汉字的过程。
这个过程是最为理想的处理过程,没有丢失信息,也没有出现任何蹩脚的信息。

分享到:
评论

相关推荐

    JAVA常见中文乱码问题解决方法

    Java编程语言在处理中文字符时可能会遇到乱码问题,这主要源于Java的源代码编码、JVM处理class文件以及不同操作系统、数据库系统之间的编码不一致。本文深入剖析了Java中文问题的根源,并提供了相应的解决方案。 一...

    Linux下Java程序中文乱码问题研究.pdf

    "Linux下Java程序中文乱码...本文研究了Linux操作系统下Java程序中文乱码问题的原因和解决方法。我们可以通过选择合适的字符集和编码方式,使用字符集转换工具,或者使用Java语言的中文支持类库来解决中文乱码问题。

    Java开发中文乱码问题解决

    在Java开发过程中,中文乱码...理解字符编码的工作原理,以及如何在Java中操作字符编码,对于避免和解决乱码问题至关重要。在实际项目开发中,养成良好的编码习惯,如始终使用UTF-8编码,可以显著减少乱码问题的出现。

    Java开发乱码问题解决方法汇总

    Java开发乱码问题解决方法汇总 Java开发中乱码问题是非常常见的问题之一,而解决这些问题需要具备一定的技术知识和经验。...如果读者在实际开发中遇到乱码问题,可以尝试使用这些方法来解决问题。

    java编程中乱码问题解决

    在Java程序中,可以通过设置系统属性或使用`setEncoding`方法来指定正确的字符集编码。 ```java System.setProperty("file.encoding", "UTF-8"); ``` 对于Web应用而言,还需要确保HTML页面和JSP页面中都正确设置了...

    Java编程中的中文问题以及解决方法

    ### Java编程中的中文问题及其解决方法 #### 一、中文问题的来源 计算机技术发展初期,操作系统主要支持单字节编码格式,这主要是为了适应英文等拉丁字母的处理需求。然而,随着全球化的推进和技术的进步,为了更...

    java插入mysql中文乱码解决

    1. **字符集不一致**:如果Java程序、JDBC驱动、MySQL服务器以及数据库表的字符集设置不一致,就会导致中文乱码。例如,如果Java程序使用的是GBK编码,而MySQL服务器使用的是UTF-8编码,则会导致乱码。 2. **连接...

    Linux下java的Swing程序乱码解决

    本文将详细探讨Linux下Java Swing程序中文乱码的原因及解决方案,帮助开发者有效解决此类问题。 ### 一、问题根源分析 #### 1. 编码设置不一致 在Linux系统中,Java应用的字符编码可能与系统默认的字符编码不同,...

    解决中文乱码问题-java

    在IT领域,尤其是在Java开发中,遇到中文乱码问题是相当常见的。这主要涉及到字符编码的处理,如果在数据传输、存储或显示过程中没有正确地指定或转换编码,就容易出现乱码现象。以下是对如何在Java中解决中文乱码...

    java国际化中文乱码问题解决包

    通过以上方法,开发者可以有效地解决Java国际化过程中遇到的中文乱码问题。`BundleEditor` 提供的工具集可以简化这个过程,提高开发效率,并确保应用程序在全球范围内提供一致且正确的用户体验。为了充分利用这个...

    java web开发解决乱码问题

    - **解决方法**:在JSP页面中,可以通过设置请求的字符集编码来解决乱码问题:`("GBK"); %>` ##### 3.5 其他特殊场景下的乱码问题 - **在表单头部设置编码**:可以在表单头部通过`; charset=UTF-8">`设置正确的...

    Java乱码问题解决

    ### Java乱码问题详解与解决方案 #### 一、问题背景 在Java开发过程中,尤其是在处理中文字符时,经常遇到字符编码不一致导致的乱码问题。由于Java默认使用Unicode编码,而在中国大陆地区,常见的字符集为GB2312...

    java解决压缩中文乱码

    在Java编程中,当涉及到文件压缩操作时,经常会遇到一个问题:中文字符在压缩过程中出现乱码。这主要是因为Java的标准库`java....通过上述方法,即使不依赖第三方库,也可以在Java程序中实现对中文文件名的完美支持。

    java中文乱码解决方案和经验

    ### Java中文乱码解决方案与经验 #### 一、字节与Unicode 在Java中处理文本时,经常会遇到中文乱码的问题。这是因为Java内部使用的是Unicode编码标准,而外部数据源如文件、网络传输等通常使用的是字节流,且可能...

    Java Web程序开发中字符乱码的原因与解决办法.pdf

    字符乱码问题是Java Web程序开发过程中经常遇到的一个问题,它会对用户界面的友好性以及信息的准确传达造成很大的影响。为了解决这个问题,我们首先要了解字符集和字符编码的相关知识,然后分析字符乱码的原因,并...

    java读写csv文件,中文乱码问题

    然而,当处理包含中文字符的CSV文件时,可能会遇到乱码问题。这个问题通常与字符编码设置有关,特别是Java的默认字符集和CSV文件本身的编码不一致时。 首先,我们需要理解Java中的字符编码。Java使用`Charset`类来...

    java传值中的乱码

    ### Java传值中的乱码问题及最简易的解决方法 在Java Web开发中,经常会遇到一个令人头疼的问题:客户端向服务器传递数据时出现乱码。这种情况不仅会影响用户体验,还可能导致程序逻辑错误。本文将深入探讨Java传值...

    java压缩zip文件解决中文乱码问题

    然而,当涉及到包含中文字符的文件或目录时,可能会遇到乱码问题。这个问题主要源于字符编码的不一致,通常需要正确设置字符集来确保中文字符在压缩和解压过程中能正确保存和读取。 首先,我们要理解ZIP格式本身并...

    Java Web编程中页面跳转乱码问题的解决方案.pdf

    然而,在实际开发过程中,程序员常常会遇到页面跳转乱码的问题,尤其是中文乱码问题,这些问题不仅消耗程序员大量的时间和精力,还可能严重影响程序开发进度,甚至导致整个应用无法正常使用。为了解决这类问题,本文...

Global site tag (gtag.js) - Google Analytics