1. 引言
在用JAVA进行开发时,偶尔在IO操作中会产生字符丢失现象。如在用BEA的WORKSHOP开发CMP EJB过程中,总是编译不通过,报错:
cannot resolve symbol
symbol : class Excetion
location: class eaitest.vip.firmorder.FirmOrderBean_g8ghds__WebLogic_CMP_RDBMS
} catch (Excetion ex) {
可以看到明显“Excetion”拼写错误。而这段代码是WORKSHOP自动生成。但是,在某些机器上,同样的工程文件,编译就能通过。联系BEA工程师,也不能解决此问题。
笔者查阅大量资料,很难找到相关问题的介绍。一次在偶尔查阅SUN的缺陷库[i]时,发现是由于GB18030中文编码问题所致。
2. 问题分析
国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,是我国计算机系统必须遵循的基础性标准之一。国家质监总局规定GB 18030过渡期(即2001年8月31日)后正式发布或出厂的产品,必须符合GB-18030相关要求。
操作系统默认内部编码一般并不是GB18030,目前已知在WINDOWS XP操作系统中,进行某些组件的升级后,会把操作系统的默认编码由GB2312变更为GB18030。
但是即便在最新发布的JDK1.4.2_06版本中,对其支持仍存在一定问题。GB18030问题主要表现是,基于java的应用,涉及GB18030编码与其它编码方案转换时,存在字符丢失现象。
问题的原因是java在处理由sun.nio.cs.ext.ExtendedCharsets提供的扩展字符集时,会进行字符缓冲。但是对于缓冲字符没有采用新的sun.nio.cs.ext包处理,而是延用原有处理方式,这种方式在多线程操作下对GB18030编码方案处理存在问题,这样导致部分字符丢失。
此问题只影响GB18030编码方案,对GB2312等中文编码方案并没有影响。
当操作系统默认编码方案为GB18030时,如果进行文件写操作,未指定编码方案情况下,java采用操作系统默认编码方案操作,这时最容易出现GB18030问题。
查看操作系统默认编码,可以运行如下java程序:
public class EchoDefaultSystemEncoding{
public static void main(String[] args){
String encoding=System.getProperty(“file.encoding”);
System.out.println(“Default System Encoding: ” + encoding);
}
}
在用WORKSHOP开发CMP EJB出现问题的操作系统默认编码即为GB18030。
由于遇到此问题的人比较少。而真正遇到时,很多人通过重新安装操作系统可以解决问题,因而这方面的资料很难找到。
3. 解决办法
最理想的解决办法就是由SUN修正此BUG。此问题早在2003年11月即提出,但是直到目前(2004/12/30),问题状态仍为“In process, bug”。
替代的解决方案主要思路是避开GB18030编码,主要有两种方法
改变操作系统默认编码方案
对于unix/linux平台,修改操作系统编码方案很简单。如在solaris平台下,运行如下命令即可改变系统编码:
LANG=zh.GBK;export LANG
对于windows平台,修改操作系统中文默认编码比较复杂。尝试把操作系统的“区域和语言选项”更改为其它地区,选用其它语言,都没有效果。与微软客户服务联系,也不能提供相应解决方案。
运行java应用时指定默认编码
在运行基于JAVA的应用时,加上参数:
java –Dfile.encoding=GB2312
把java应用的默认编码方案与GB2312硬绑定,即在未指明编码方案时,采用GB2312编码。
如果针对每个应用,进行上述修改,工作量很大。有些应用里面又隐式调用外部JAVA应用,更增加修正的难度。比较可行的办法是对java的运行文件进行修正,令其在运行时自动加上“-Dfile.encoding=GB2312”参数。
建议windows平台采用本方法进行修正。方案如下:
1、改名原java.exe,javaw.exe,如改为javabak.exe,javawbak.exe
2、重写java.exe和javaw.exe,令其运行时调用javabak.exe,javawbak.exe,并在运行时加上“-Dfile.encoding”参数。
如下c代码即可完成上述功能:
#include "string.h"
#include "stdlib.h"
int main(int argc, char* argv[])
{
char arg[100000] = "javabak.exe -Dfile.encoding=GB2312 ";
for(int i=1; i<argc; i++){
strcat(arg,argv[i]);
strcat(arg, " ");
}
system(arg);
return 0;
}
编译后(注意修改arg值),生成的文件命名为java.exe和javaw.exe,放置在<JAVA_HOME>/bin和<JAVA_HOME>/jre/bin目录下,即可。
经实践,此办法可以解决GB18030问题,并且不会带来其它隐患。唯一的缺点是在运行JAVA应用时,会有一个额外的DOS窗口打开,此窗口可以关闭,不会对应用运行带来影响。
4. 总结
在应用开发中,中文编码一直是一个比较麻烦的问题。尽管目前GB18030是国家强制性标准,有着各种各样的优点,但由于其推出时间尚短,在应用方面对其支持还不够完善,还是应尽可能采用GB2312等兼容性比较强的中文编码方案。
本文给出的解决方案,不仅适用于解决JAVA平台对GB18030支持问题,而且,也为指定通用JAVA运行默认参数,提供了另一种思路。
--------------------------------------------------------------------------------
参考文献
[i] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4954023
分享到:
相关推荐
这意味着,如果尝试读取一个UTF-8编码的文件,Reader会错误地使用GBK进行解码,导致数据丢失或乱码。 为了在Java中进行精确的编码控制,可以使用`InputStreamReader`和`OutputStreamWriter`,它们允许指定字符编码...
### Java字符编码问题详解 #### 一、引言 在Java开发过程中,字符编码问题是一个常见且容易引发各种隐藏问题的领域。不正确的字符编码处理可能导致数据丢失、乱码甚至是程序异常。本文将深入探讨Java中的字符编码...
要获取Java字符串的字节序列(即编码),可以使用`getBytes()`方法。此方法默认使用平台的默认编码,通常为UTF-8,但也可以指定其他编码,如`getBytes("GBK")`。如果需要确定字符串的原始编码,需要额外的信息,...
总之,解决Java读写TXT文件中文乱码问题的关键在于明确文件的编码类型并在操作文件时指定正确的编码。通过上述方法,你可以确保在处理包含中文字符的TXT文件时,不会出现乱码现象。在实际开发中,要养成良好的编码...
Java字符集基础知识与问题 字符集编码是计算机处理文本数据的基础,不同的编码方式适用于不同的应用场景。本文主要讨论编码的基本知识,特别是与Java相关的部分,包括ISO8859-1、GB2312/GBK、Unicode以及UTF编码。...
10. **排查与调试**:当遇到乱码问题时,可以尝试用十六进制查看工具检查文件内容,找出可能的编码问题;也可以使用字符映射表来识别乱码的可能来源。 总结来说,解决“传递汉字丢失或乱码”问题的关键在于理解和...
java aspose word 上传到服务器 导出的word 中文字体乱码 的问题 java aspose java aspose word 上传到服务器 导出的word 中文字体乱码 的问题 java aspose java aspose word 上传到服务器 导出的word 中文字体乱码 ...
Java字符编码转换是Java开发中一个重要的概念,涉及到数据的正确读取、存储和传输。在Java中,编码转换通常发生在以下几个场景: 1. **JVM启动与系统属性**: JVM启动时,会根据操作系统的环境设置一些系统属性,...
Java字符集是Java编程语言中处理字符编码的基础概念,它对于理解如何在程序中正确地存储、处理和传输文本至关重要。在Java中,字符集主要指的是Unicode字符集,特别是其子集UTF-8,它是Java默认使用的字符编码。Java...
6. **处理中文乱码**: 如果遇到中文乱码问题,检查PDF文档的编码设置,确保与转换代码中设置的编码一致。如果需要,可以使用`PDType0Font`来加载系统中的中文字体。 7. **关闭文档**: 转换完成后,别忘了调用`...
Java编程中的中文乱码问题是一个常见但棘手的挑战,主要源于编码格式的不匹配和转换过程中的错误。本文深入探讨了这个问题,并提供了解决方案。 首先,我们要理解中文字符编码的历史背景。早期的计算机系统主要支持...
在实际应用中,字符编码问题可能导致乱码、数据丢失或者无法正确解析的问题。例如,从GBK编码的文本读取数据并试图用UTF-8解码,就会导致无法识别的字符。因此,这样的工具通常会包含以下功能: 1. **编码识别**:...
在Java编程语言中,处理字符串编码是至关重要的,因为正确的编码和...理解并正确使用这些方法可以避免常见的编码问题,如乱码和数据丢失。在开发过程中,始终记住指定正确的编码,特别是在跨平台或处理多语言内容时。
当尝试用不支持某些字符的编码来编码字符串时,可能会导致乱码或者丢失信息。例如,用ISO-8859-1编码中文字符,只会得到半个字符,因为它是单字节编码,无法表示完整的多字节字符。 7. **安全编码实践**: 应避免...
Java字符串的编解码涉及到字符集(Charset)的概念,字符集是用于表示文本的一套符号及其对应的数值。...在处理多语言或跨平台的项目时,对编码的理解和正确使用至关重要,可以避免许多常见的乱码问题。
开发者应确保所有输入输出的编码一致,特别是在不同编码环境下工作时,要谨慎进行编码转换,避免因编码不匹配导致的数据丢失或乱码问题。通过掌握上述编码转换技巧,可以有效提升Java应用程序对中文等非英文字符的...
在版本1.6.6中,它针对中文字符的处理进行了优化,确保在反编译过程中不会出现乱码问题,这对于处理包含中文字符的Java项目来说尤其重要。 **Java反编译基础** Java反编译是将Java字节码(.class文件)转换回源...
Java字符流是Java IO系统的重要组成部分,主要用于处理文本数据。在这个名为"java字符流练习-电话本管理系统"的项目中,开发者使用了Java的字符流API来实现一个电话本管理的功能。电话本管理系统通常包括添加联系人...
在实际项目中,通过这种方式配置的过滤器可以有效避免由字符编码引起的乱码问题。比如,在一个涉及多语言用户的电子商务平台中,用户可能来自不同的国家和地区,他们提交的数据也可能包含多种语言文字。通过上述配置...