欢迎光临
我们一直在努力

Java字符丢失与中文编码-JSP教程,Java技巧及代码

建站超值云服务器,限时71元/月

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运行默认参数,提供了另一种思路。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » Java字符丢失与中文编码-JSP教程,Java技巧及代码
分享到: 更多 (0)