JAVA总结(二):字符的编码与解码

中文字符出现乱码的原因是因为采用了错误的解码方式,换句话说,也就是没有采用与字符编码一致的方式进行解码。

那如何将乱码字符还原呢?需要分为以下几步:
1. 将当前的乱码字符以当前解码的方式编码为二进制数组,这也是还原过程;
2. 然后以正确的方式(即原编码方式)进行解码;

下面以接收到的乱码字符“鍥介檯绫冲叞”为例,再次讲解还原过程。
1. 首先获取当前乱码字符的解码方式;

#   获取默认的字符编码,本机测试为GBK
Charset.defaultCharset()
  1. 将其进行重新编码,还原为二进制数组;
"鍥介檯绫冲叞".getBytes("GBK")
  1. 对二进制数组重新进行解码;
#   最后输出为国际米兰
new String("鍥介檯绫冲叞".getBytes("GBK"), "UTF-8")

至于为什么需要重新编码与解码?很简单,这是因为每种字符编码都采用不同的方式存储字符,如UTF-8采用3个字节存储汉字,而GBK采用2个字节存储汉字。

下面我们以一个模拟的例子来加深印象:

String str = "国际米兰";
//  用GBK进行解码,结果出现乱码
String iso2GBK = new String(str.getBytes(Charset.defaultCharset()), "GBK");
//  出现乱码
System.out.println(iso2GBK);
//  还原解码,用GBK进行编码
byte[] sourceArr = iso2GBK.getBytes("GBK");
//  再次进行解码,还原字符串
String sourceStr = new String(sourceArr, Charset.defaultCharset());
System.out.println(sourceStr);

这里需要特别注意的是,在String.getBytes()方法的调用中,如果字符集选择不当,则可能出现二进制编码丢失的现象,从而导致字符难以还原的现象,如将上面的字符编码为ISO-8859
-1,由于字节存储的差异,将导致大量的二进制码丢失,最后出现字符难以还原的现象,请看下面的编码结果。

String str = "国际米兰";
#   输出结果为12,一个汉字三个字节
System.out.println(str.getBytes("UTF-8").length);
#   输出结果为4,一个汉字只有一个字节
System.out.println(str.getBytes("ISO-8859-1").length);

基于上面的输出,我们得到如下的结论:
1. 如果是UTF-8的字符,经过GB2312、GBK、ISO-8859-1编码,则会丢失大量字节,字符无法还原,GBK到ISO-8859-1类似,即多字节到少字节编码,必然出现字节丢失现象,反之,则出现字节增多现象;
2. 如果以默认的方式编码后,再以更多字节的方式解码,如GB2312转UTF-8,则可能会出现字符减少现象(依赖于字节的含义,也可能增多),但数据多半已损坏,不可还原,但以更少字节方式解码,如果满足奇偶关系,则字符可还原,参见如下例子:

//  默认为GBK编码
String str = "国际米兰";
//  用ISO-8859-1解码
String cc = new String(str.getBytes(Charset.defaultCharset()), "ISO-8859-1");
//  再次编码与解码,将字符还原
System.out.println(new String(cc.getBytes("ISO-8859-1"), "GB2312"));
  1. 编码与解码并不满足可逆条件,请使用中密切注意。

总结

在对字符进行编码时,一定要注意采用相同的编码(与字符的默认编码相同),否则会出现字符的二进制数组丢失现象,从而导致字符受到损坏,再也无法还原,类似地,在使用native2ascii命令,也应该满足相应的规则,如下:

#  encoding是指输入文件的编码方式,这里是指1.txt,千万要指定正确,否则出现错误的结果
native2ascii -encoding GBK 1.txt 2.txt
#   反转,这里的encoding是指输出文件的编码方式
native2ascii -reverse -encoding GBK 2.txt 3.txt
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值