最近被文件读写的乱码搞郁闷了,现在来研究一下。
首先了解一下字符编码的历史。
ASCII,这无需多说(American Standard Code for Information Interchange)美国信息交换标准代码,是一套基于拉丁字母的电脑编码系统,至今为止共定义了128个字符,可以显示现代英语。但是随着万维网的发展,多语言的处理使得该标准不再适用,逐渐被之后的Unicode所取代。
Unicode,是计算机科学领域里的一项业界标准,随着通用字符集的标准而发展,至今已经收录了超过十万个字符。Unicode备受认可,并广泛地应用于计算机软件的国际化与本地化过程中。值得一提的是(没有具体验证),XML和Java采用的都是Unicode编码。统一码联盟在1991年首次发布了The Unicode Standard,并逐渐发展成现在的样子。
其次,关于文件的编码方式。
对于具体的编码方式,被困惑了很久,后来发现其实是很多的概念是混淆的。
为了实现编码的同一,有两个相互独立的机构共同的进行工作,他们分别是,国际标准化组织(ISO)和统一码联盟。说到这里,突然想起来了秦始皇灭六国,统一度量和文字,这难道不是一个道理?!
实际上,Unicode编码系统分为编码方式和实现方式两个层次。
所谓编码方式与通用字符集的概念相关,它确定了语言中的每个字符对应的Unicode编码是确定的。目前实际应用的统一码版本对应于UCS-2,使用16位的编码空间。也就是每个字符占用2个字节。这样理论上一共最多可以表示216(即65536)个字符。基本满足各种语言的使用。但是,Unicode对中文的支持不怎么好,资料显示,中、日、韩的三种文字占用了Unicode中0x3000到0x9FFF的部分。因为简体和繁体总共有六七万个汉字,而UCS-2最多能表示65536个,才六万 多个,所以Unicode只能排除一些几乎不用的汉字,好在常用的简体汉字也不过七千多个,为了能表示所有汉字,Unicode也有UCS-4规范,就是用 4个字节来编码字符。
而Unicode的实现方式则是比编码方式复杂的多的问题,这牵扯到具体的操作系统甚至是硬件对于字节的存放方式。简单的说,由于系统和平台的设计不一样,出于硬件,效率,节省空间等等因素的影响,Unicode的具体实现方式有所不同。这里所谓的实现方式从直观上来说,就是写入到文件中的具体数据有所不同。因此,Unicode的实现方式,也称为Unicode的转换格式,即Unicode转换格式(Unicode Transformation Format,简称为UTF)。
而我常常所熟见但却不甚清楚的UTF-8编码就是此类编码方式中的一种。下面简单说明一下。
UTF-8是一种针对Unicode的变长字符编码。他可以表示Unicode标准中的任何字符,并且与ASCII兼容,使得原来针对ASCII的程序或者软件不做或者只做少量的改变即可继续使用。具体来说,UTF-8针对8bit为单位的UCS进行转换,选择边长字节进行存储,其最大长度甚至可以达到六个字节。这样做的最大的好处就是对ASCII的兼容,因为所有ASCII的字符都可以保持原有的字符编码不变。
UCS编码(16进制) | UTF-8 字节流(二进制) |
0000 - 007F | 0xxxxxxx |
0080 - 07FF | 110xxxxx 10xxxxxx |
0800 - FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
举个例子:
平台:Windows7,notepad
输入文本:
1 hello 2 你好
在通常情况下,我们使用ASCII来保存对应的*.txt文档。
这次我分为ASCII,Unicode,UTF-8,Unicode big Endian三种方式来保存,并在winhex下来观察他们保存中英文的情况。