Java中文乱码——1、Java编解码基础
来源:互联网 发布:iis7 php http503 编辑:程序博客网 时间:2024/05/21 15:00
相信大家平时遇到过不少中文乱码问题,大家是怎么解决的,是使用new String(s.getByte(“ISO-8859-1"), “GBK")这样的方式吗?如果是的话,那么大家有没有问过自己以下问题:
a)s.getByte(“ISO-8859-1")做了什么?
b)newString(byte[], “GBK")又做了什么? c)这个转换过程的意义是干什么?
d)转码前后,占内存大小改变了吗?变大还是变小了?
一、常见字符集简介
详见http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/
ASCII
7bits,不支持中文
ISO-8859-1
8bits,不支持中文
UTF-8
西文1字节,中文3字节
GBK/GB2312/GB18030
西文1字节,中文一般都是2字节
Unicode
2字节,也称utf-16,可以和任意其它字符集互转
二、编解码基础
在特定字符集中,字符和code一一对应,比如:unicode中汉字“中”对应code 0x4e2d。
Java内部采用unicode来表示一个字符,我们将unicode字符转换成字节的过程,称为“编码”;将字节恢复成unicode字符的过程,称为“解码”。 此处要强调3点:
1、String内部包含一个字符数组char[]
2、该char[]采用Unicode,也就是UTF-16字符集来表示
3、该char[]可以看成是1个byte[],其中当然1char=2bytes
此外,个人更喜欢把编解码过程统一看成byte[]之间的转换。假设编解码都采用charsetA,那么其中前者是从UTF-16到charsetA的转换,后者则相反。
三、转码过程理解
1、s.getByte(“ISO-8859-1")做了什么
它的意思是说,将字符串s中的char[]用ISO-8859-1 code序列byte[]来表示。即char[] => ISO-8859-1 byte[]
也可以理解成
UTF-16 byte[] a => ISO-8859-1 byte[] b
2、new String(byte[], “GBK")做了什么
它的意思是说,我这里有个byte数组,请先将它看成GBK的code序列,然后再将每个code解析为可读字符。即
GBK byte[] => char[]
或者说
GBK byte[] b => UTF-16 byte[] c
3、这个转换过程的意义是什么
把两步连在一起,就成了UTF-16 byte[] a => ISO-8859-1 byte[] b = GBK byte[] b => UTF-16 byte[] c
再者,乱码一般发生在io过程中,io采用byte[]来传输数据,因此其实最前面还有一个过程
ISO-8859-1 byte[] b => UTF-16 byte[] a 把这三步连在一起就成了
ISO-8859-1 byte[] b => UTF-16 byte[] a => ISO-8859-1 byte[] b = GBK byte[] b => UTF-16 byte[] c 于是,它的含义就出来了:把一个原本以ISO-8859-1来理解的byte[] b,重新以GBK来理解。
4、转码前后,占内存大小改变了吗?变大还是变小了?
由于UTF-16是定长编码的,因此,要看内存大小是否改变,只需要看分别以ISO-8859-1和GBK来理解同一个byte[]时,最终的字符数是否会变化。
很显然,如果byte[]中全都是ascii字符,那么字符数肯定一样,否则肯定就不一样。
那么是变大还是变小了?我们知道ISO-8859-1是单字节的,GBK是可变字节的,那么如果两者最终得到的字节数不一样,肯定是按照ISO-8859-1的方式去理解会得到更多的字符。
总结起来就是:如果转码后不包含中文,则大小不变,否则变小。
不过,实话说,这个结论貌似也没有什么实用价值。
四、默认编码
聊完转码过程,我们再聊聊默认编码的问题。
我们知道s.getByte("ISO-8859-1")是指UTF-16 byte[] a => ISO-8859-1 byte[] b,那么s.getByte()呢?类似地,newString(byte[], "GBK")是指GBK byte[] b => UTF-16 byte[] c,那么newString(byte[])呢?
其实,当我们没有指定编码集时,系统会默认指定一个编码集,那么这个默认编码集是怎么指定的?
首先、它由JVM参数file.encoding决定;
其次、如果没有指定file.encoding,则它由系统变量决定。Linux下由环境编码NLS_LANG决定;Window下也是由环境变量NLS_LANG决定;在Eclipse下则是由启动脚本common页下的“Encoding设置”决定; 最后、如果真的是啥都没指定,那么默认就是ISO-8859-1
参考
http://openwebx.org/docs/requestcontexts.html#webx3.requestcontexts.setlocale 0 0
- Java中文乱码——1、Java编解码基础
- Web中文乱码——3、Webx编解码基础
- Web中文乱码——1、SpringMVC+Jetty编解码基础
- JS和JAVA编解码(乱码)问题
- java基础----编解码 转换流
- Java:Base64编解码
- Java中的编解码
- Java的编解码
- Java Base64编解码
- java web 编解码
- java编解码技术
- java编解码base64
- 编解码基础1
- java中文乱码解决之道(五)—–java是如何编码解码的
- 字符串中文乱码、编解码问题
- 黑马程序员——JAVA 编解码表与GUI
- 黑马程序员——Java编解码表与GUI
- java中文乱码解决之道(六)—–javaWeb中的编码解码
- 其它中文乱码——2、Oracle视图乱码
- 会用.gitignore么?
- PHP匹配中文的正则表达式
- IOS ARC内存管理,提高效率避免内存泄露
- 从零开始学习Windows WDF驱动程序开发
- Java中文乱码——1、Java编解码基础
- nignx中Cache-Control标头和OutputCache的使用介绍
- 一个有用的Perl修改文件的模块
- 如何判断机器是大端还是小端
- python中元组的常用方法
- 利用RenderScript对图像快速高斯模糊(一)
- 模式识别研发中的盲人摸象问题
- 第三周作业-实现随机点名的签到程序和计算闰年的简单程序
- 《算法概论》第二周作业-RSA算法实现