java编码格式总结

乱码一直是一个很让人头疼的问题,这次往oracle的Blob里面写东西的时候,又出现了乱码。不过这次成功解决了,看了几篇讲java编码格式的文章恍然大悟,原理其实很简单,大家可以到这几个链接看看,他们写的很清楚:

 

 

http://lavasoft.blog.51cto.com/62575/273608

 

http://developer.51cto.com/art/200906/132635.htm

 

http://topic.csdn.net/u/20080822/11/69048375-6928-4a30-a58a-3ded53dc53f2.html

 

http://blog.csdn.net/fangao2620/archive/2008/02/25/2120221.aspx

 

http://jiangzhengjun.iteye.com/blog/512072

 

http://ayagen.iteye.com/blog/587653

 

其实,说白了就是,java中的String永远都是unicode编码的,以它作为中间结果转化成各种不同的编码格式,比如:

 

        String str = "中文";
        byte[] utf8b = str.getBytes("UTF-8");
        byte[] gbkb = str.getBytes("GBK");

        // 没有乱码
        System.out.println(new String(utf8b, "UTF-8"));

        // 没有乱码
        System.out.println(new String(gbkb, "GBK"));

        // 有乱码

        System.out.println(new String(gbkb, "UTF-8"));

        // 有乱码
        System.out.println(new String(utf8b, "GBK"));

 

byte数组utf8b和gbkb是不一样的,是转化成各自编码格式后的二进制数组,而new String(utf8b, "UTF-8")与new String(gbkb, "GBK")是一样的都是以Unicode编码保存。

 

我们可以来分析一下:

1. 当执行以下时:

byte[] utf8b = str.getBytes("UTF-8");
 

jvm实际上是做了这样的转化 UNICODE => UTF-8,就是将Jvm内存中的unicode编码二进制码转化成UTF-8格式的二进制码然后赋值给byte[] utf8b 。这个转化的过程我们不用管,jvm会根据一个编码格式对照表来转化。

 

2. 当执行后面代码:

new String(utf8b, "UTF-8")
 

实际上第二个参数"UTF-8"告诉jvm:“当前utf8b的编码格式是"UTF-8",你就以这个格式转化成unicode吧!”。也就是将utf8b转化成unicode再存入Jvm的内存,utf8=>unicode。(这个参数应该是为了告诉jvm使用“UTF-8”的编码格式对照表来转化)

 

很多时候出现乱码实际上就是第二个过程出现了问题,比如有个页面是以“UTF-8”方式编码的,当你提交了一个表单后,浏览器将表单的内容以“UTF-8”格式编码后以HTTP POST请求的方式发送到后台。当HTTP Post请求到达servlet后,提交的表单数据都是“UTF-8”编码的二进制数据。当你调用request.getParameter("someParam")的时候,servlet实际上将inputstream中“someParam”的数据取出,然后将其转化成字符转。为了便于理解,我们假设这段数据是一个byte[] pb,当你调用了request.getParameter("someParam")时相当于调用了new String(pb),由于你没有指定使用何种方式编码,因此,jvm使用系统默认的编码格式编码,这时如果你的系统默认编码格式是“UTF-8”那就相当与调用了

new String(utf8b, "UTF-8")
 

不会出现乱码。但是如果你很倒霉,你的默认编码格式是“GBK”那么就好比调用了

new String(utf8b, "GBK")
 

乱码就不可避免了。因为,jvm会试图将原来是"UTF-8"格式的数据使用"GBK"的对照表来转化成unicode,结果当然是牛头不对马嘴了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值