欢迎来到天天文库
浏览记录
ID:61459196
大小:1021.50 KB
页数:38页
时间:2021-02-01
《java字符集编码乱码详解.doc》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、一.编码与乱码(01)---编码基础Unicode中文“艺”字:827A二进制的“艺”字编码:1000001001111010UTF-8的中文编码规则:1110xxxx10xxxxxx10xxxxxxUTF-8的“艺”字编码:1110【1000】10【0010】【01】10【11】【1010】UTF-8的转码过程解析:8对应的1000被填入第一字节剩余的4位。2对应的0010被填入第2字节剩余的前4位。7对应的0111被拆开,前2位01被填入第2字节的后两位,后2位1被填入第3字节的前2位。A对应的1010被填入第3字节的后4位。UTF-8的最终编码结果:---对应E8;---对应8
2、9;---对应BA。所以最终的UTF-8编码就是%E8%89%BAUnicode到UTF-8的转换:Unicode的16进制编码<-->对应的2进制编码<-->UTF-8规范的2进制编码<-->UTF-8规范的16进制编码也就是说假如在Java的底层JVM,由于采用的是Unicode编码字符集,对“艺”字的编码是827A。那么在网络传输的过程中,我们当然不能直接传输827A这个字符过去代表艺”这个汉字,而必须要转换成0,1这样的字节流,才能在网络中传输。所以说UTF-8是一种为了方便网路传输,节省传输数量,而对Unicode的字符集的字符编号进行转换,从定长的2个字节(16进制)转换
3、成1~3个的变长字节(2进制)表示的转换格式。由于Unicode采用的是2个字节的编码方式,而UTF-8转换后可能是1~3个字节,所以同一个汉字,在Unicode中的编码和经UTF-8转换后的编码值肯定是不同的。就好像艺字的Unicode编码是827A,经转换后的3个字节是E889BA。所以说对于英文字符来说,采用UTF-8对Unicode编码转换后节省了一倍的传输成本(由定长的2个字节变长1个字节),但对于原本双字节的东亚字符来说,反而增加了成本,是原来的1.5倍。小结:①ASCII、GB2312、GBK、GB18030、Big5、Unicode都是字符集的名称。它们定义了采用1~
4、2个字节的编码规范,为每个字符赋予了一个独一无二的编号。这个编号就是我们所说的“字符编码”。②Unicode字符集定义的字符编码并不适合直接通过网络传输表达,因为它们必须转换成像0101这样的二进制字节流传输。所以就出现了不同的转换规范实现方式:UTF-8,TF-16等。这些不同的转换规范转换后的编码值和Unicode是不同的。对于UTF-8来说,它采用变长字节表示所有Unicode字符,对于英文来说和ASCII兼容,对于东亚字符来说,是原来传输成本的1.5倍。所以采用UTF-8编码转换方式虽然有利于统一,但增加了中文等双字节字符的传输成本。UTF-8采用首字节的高位"1"的个数表示
5、字符的编码长度。例如在Unicode的编码规范中:汉字的表示区间为U-至U-0000FFFF对应的UTF-8的转换规则为:1110xxxx10xxxxxx10xxxxxx首字节3个1代表这个字符的编码长度为3个字节。如果是2个1则表示2个字节③在底层的平台中如JVM,采用的是Unicode字符集,当要把这些字符通过网络传输时,可以选择通过UTF-8或其他(例如GB2312)编码转换方式对要传输的字符编码进行转换。如果目的端也是采用Unicode字符集,那么UTF-8转换后的编码可以被正常识别并解码成最终对应的Unicode字符集编号。如果是非Unicode字符集平台则可能出现乱码(U
6、TF-8中汉字的3个连续字节被解析成GB2312的2个连续字节,出现丢失)。所以推荐在传输的两端采用Unicode字符集编码,在传输方式上采用UTF-8转换方式。javac命令是以系统默认编码读入源文件,然后按Unicode进行编码的。(备注:每个文件都有自己的编码,javac命令按照默认的文件编码读入,但是在将.java文件转换成.class的过程中,javac会将所有的字符转化成unicode的格式保存。)在运行时JVM也是采用unicode编码的,并且默认输入和输出使用的都是操作系统的默认编码。也就是说在newString(bytes[,encode])中,系统认为输入的byt
7、es是编码为encode的字节流(如果不指定encode,那么就是默认使用系统的编码方式),换句话说,如果按encode来翻译bytes才能得到正确的原始字符,这个字符最后要在java中保存,它还是要从这个encode转换成Unicode的。也就是说,假如我们需要从磁盘文件、数据库记录、网络传输一些字符,保存到Java的变量中,要经历由bytes-->encode字符-->Unicode字符的转换(例如newString(bytes,encode));而要
此文档下载收益归作者所有