前几天在使用中兴的MM7接口开发一个彩信的应用,可是在测试的时候,手机收到的文本内容总是一堆乱码,不管怎么修改参数问题都得不到解决,于是就狠狠的琢磨和研究了下关于编码的内容,最终成功解决了乱码的问题。
我们都知道Java语言使用的是Unicode编码。可是大家是否真的已经理解了这句话的含义? Unicode编码和我们常用的UTF-8,GBK有什么关系呢? 那接下来就来讨论下这个话题。
不知大家还有没想过,我们在Java代码里面定义一个字符串字面量的时候,该字符串在JVM中的编码是什么? 是的,上面也说了Java语言用的是Unicode编码,所以这样定义的字符串字面量自然就是Unicode编码表示的。 然而除了这种程序内部的数据外,我们经常还会从外部获取各种各样的数据让程序处理,例如通过IO从硬盘上读取文件,通过JDBC查询数据库等,而这些数据的编码格式是多种多样的,例如有的可能是UTF-8,有的可能是GBK等,那么这样的一些数据在JVM中又是以什么编码表示的呢?
上面提到了几个问题,现在返回去简单的说说编码,当然这里只是粗略的提及,毕竟网上这方面的内容很多。
我们首先要弄清楚两个概念,“字符集编码”和“编码格式”。所谓“字符集编码”就是由某个组织制定的一张“字符与编号的映射关系表”,例如: 10001 == “我”, 10002 = “们”。 我们所谓的Unicode字符集就是这样的一张关系表。
而UTF-8是一种实现了Unicode字符集中部分字符编码的“编码格式”,它存在目的是为了保存或者传输数据用的。那么既然在字符集中已经有了映射关系了,为什么还要再来编码。原因好几个,例如考虑文件大小的问题,使用效率的问题,和其他字符集区分的问题等。
那么UTF-8编码又是对Unicode字符集中的哪部分编码呢? 就是“字符编号”,例如上面的10001,10002. 而对于UTF-8的编码规则可以网上查阅.
那现在我们就应该清楚了,在JVM中表示字符串“我们”使用的编码为“1000110002”这样的格式,也就是使用的是Unicode的编号。那当我们通过IO将一个以UTF-8编码的文本文件读入内存的时候,很可能我们会使用到这样的代码:
new InputStreamReader(new FileInputStream(file),"UTF-8")
这里指定的“UTF-8”就是文件的编码格式,它的目的是告诉负责解码的对象要按照“UTF-8”的编码格式来解码成JVM使用的Unicode编码。那如果我们这里指定为“GBK”的话,我们所得到的可就是一堆乱码啦。
如果String content = (文件内容) 。 那么这个content在这个时候已经是Unicode编码了。不知道现在为止是否应该明白了些什么。
如果你看到这样的代码:
String msg = "我是一个字符串" ;
String res = new String(msg.getBytes("utf-8"),"GBK") ;
那这里的res打印出来也就是一堆乱码了。这里的操作过程其实是:
1,将Unicode编码的msg按照UTF-8的编码格式进行编码,从而得到UTF-8编码的字节数组。
2,将字节数组按照GBK的编码格式来解码成Unicode编码的字符
3,可惜UTF-8和GBK不兼容,他们使用了不同的编码集,所以乱码出来啦
在进行http请求的时候,我们需要告诉对方我们发送的数据的编码格式是什么,如果对方按照我们的告知的编码格式来解码,而我们却把错误的编码格式告诉了对方,那么接下来的事情就是对方收到了一堆的乱码。
还有就是我们在进行这样的操作的时候:"我是一个字符串".getBytes(); 可要小心了,这个时候得到的字节数组可是你操作系统默认的编码格式(当然我们还可以在启动的时候指定我们默认的编码格式)。
以上的内容大概的讲了下关于java中编码的问题,也算是一个抛砖引玉的过程,欢迎指正。
本文出自 “因简单而自在” 博客,请务必保留此出处http://dengshuangfu.blog.51cto.com/8794650/1729990
原文地址:http://dengshuangfu.blog.51cto.com/8794650/1729990