编码问题(UTF-8、gb2312、unicode)
相信大家很多人跟我一样,对于编码一直感觉云山雾罩,说知道吧?就知道gb2312是中文编码,一看见乱码,就知道是编码出了问题,但是是哪儿出问题,为什么出问题,除了蒙,还是蒙。尤其是弄好了之后,有人问:为什么呢。自己也不知道,就说:反正就是这样的,用什么编码就用什么解码。为什么,鬼知道。
其实问题还是理解了之后,才能真正的明白为什么会这样,而且编码这个问题,也不是那么深奥,在网上搜索了一些资料,算是一直以来对编码问题的一个解决吧,最让人明白的资料有两个,第一个:
http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html
这个关于编码,我认为是最清楚的了,刚开始看完之后,觉得自己是真明白了,gb2312只是一个字符集,而unicode是所有能用到的字符的一个总集,utf-8是一种编码。它的字符集就是unicode。而且unicode是全人类达成共识的巨大的字符集,包括了gb2312字符集。
有了这个“底气”之后,就开始了自己的探索了:
1、用记事本一个写一个xml,如下:
XMLcode
<?xmlversion="1.0"encoding="gb2312"?>
<root>
<person>hi,大美女你好</person>
</root>
将这个记事本保存为utf-8格式,然后打开,乱码,想也没想,感觉就是:用utf-8编码的文件,用gb2312的去解码,有的utf-8字符gb2312都没有,肯定会出问题了。。。(这个理解是错误的!!!)
2、用记事本一个写一个xml,如下:
XMLcode
<?xmlversion="1.0"encoding="utf-8"?>
<root>
<person>hi,大美女你好</person>
</root>
将这个记事本保存为ansi格式(在简体中文的操作系统下,就是gb2312编码),然后打开,乱码???为什么呢?unicode编码不是包含了gb2312的字符集吗?按说应该能解析啊???(延续了第一个的想法,仅仅以字符集的大小去判断,还是错误的)
没办法,只能继续网上找答案了,于是第二个资料出现了。
http://social.msdn.microsoft.com...-a207-fe30523cc5a4/
对于这个问题是这样说的:“UTF-8中包含所有gb2312中的字符的定义但是每个字符的编号却不是完全对应的所以就会出现页面的中文字不能对应的情况”
答案详见4楼RaymondTang版主的答案。
这样的话,就可以解释了为什么utf-8解析不了gb2312中的字符了。
但是,我觉得这个答案还是有问题,像RaymondTang版主所说,“每个字符的编号却不是完全对应的”,他的意思,应该是gb2312中的编码和utf-8的编码编号是不一样的,所以不能解析出正确的字符。而如果仅仅是编码不一样,那至少也不会变化太大,应该是差不多还是个汉字吧?为啥成乱码呢?
于是,我又仔细看了看第一篇文章,感觉发现了问题的所在:“GB2312以及GBK字符集,限定了使用最多2个字节来编码所有字符,并且规定了字节序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备上的字节流了。”,而:“虽然每个字符在Unicode字符集中都能找到唯一确定的编号(字符码,又称Unicode码),但是决定最终字节流的却是具体的字符编码”,这时,就由utf-8来决定了。简单的来说,就是字符流被打乱了,utf-8是变长编码的,它不能按照gb2312那样解析字节流。所以出现了乱码。
所以,终归到底,unicode是包含了gb2312中的字符集,但是每种编码解码方式不一样,也就是说,utf-8编码是一种规则,他自己编码的字节流,需要用自己的规则去解码,如果不一致,就会出现乱码情况。这就是根源所在。
期间还发现了个挺有趣的事情:当新建文本文档只输入“联通”2字保存再打开时将是乱码。
详见:http://baike.baidu.com/view/1273097.htm
这个帖子是我自己的一个总结,以备啥时候忘了能提醒自己,同时希望能对像我一样不明白的一些童鞋有些帮助,让那些早就深刻理解这些东西的人来说见笑了。。。