编码格式的比较。

按照ISO-8859-1编码

经常会出现中文编程“?”,很可能就是错误的使用了ISO-8859-1这个编码导致的。中文字符经过ISO-8859-1编码会丢失信息,通常我们称之为“黑洞”,他会把不认识的字符吸收掉。由于现在大部分基础的Java框架或系统默认的字符集编码都是ISO-8859-1,所以很容易出现乱码问题。

按照GB2312编码

GB2312对应的Charset是sun.nio.cs.ext.EUC_CN,而对应的CharsetDecoder编码类是sun.nio.cs.ext.DoubleByte。GB2312字符集有一个从char到byte的码表,不同的祖父编码就是从这个码表找到与每个字符对应的字节,然后拼装成byte数组。查表规则如下:
    c2b[c2bIndex[char >> 8]] + (char & 0xff)]
如果查到的码位值大于0xff,则是双字节,否则是单字节。双字节高8位作为第1个字节,低8位作为第2个字节。
GB2312只支持6763个汉字,所以并不是所有汉字都能够用GB2312编码。

按照GBK编码

GBK与GB2312的编码结果是一样的,由此可以得出GBK编码是兼容GB2312编码的,他们的编码算法也是一样的。不同的是,他们的码表长度不一样,GBK包含的汉字字符更多。所以只要是经过GB2312编码的汉字都可以用GBK进行解码,反之则不然。

按照UTF-16编码

用UTF-16编码将char数组放大了1倍,单字节范围内的字符在高位补0变成两个字节,中文字符也变成两个字节。从UTF-16编码规则来看,仅仅将字符的高位和低位进行拆分变成两个字节,特点是编码效率非常高,规则很简单。由于不同处理器对2字节的处理方式不同,有Big-endian(高位字节在前,低位字节在后)或Little-endian(低位字节在前,高位字节在后)编码。在对字符串进行编码时需要指明到底是Big-endian还是Little-endian,所以前面有两个字节用来保存BYTE_ORDER_MARK值,UTF-16是用定长16位(2字节)来表示的UCS-2或Unicode转换格式,通过代理来访问BMP之外的字符编码。

按照UTF-8编码

UTF-16虽然编码效率很高,但是对单子接范围内的字符也放大了1倍,这无形浪费了存储空间。另外UTF-16采用顺序编码,不能对单个字符的编码值进行校验,如果中间的一个字符码值损坏,后面的所有码值都将受影响。而UTF-8不存在这些问题,UTF-8对单字节范围内的字符仍然用1个字节表示,对汉字采用3个字节表示。

对几种编码格式的比较

对于中文字符,上述几种编码格式都能处理,GB2312与GBK编码规则类似,但是GBK范围更大,他能处理所有汉字字符,所以将GB2312与GBK进行比较,应该选择GBK。UTF-16与UTF-8都是处理Unicode编码,他们的编码规则不太相同。相对来说,UTF-16的编码效率较高,从字符到字节的相互转换更简单,进行字符串操作也更好。他适合在本地磁盘和内存之间使用,可以进行字符和字节之间的快速切换,如Java的内存编码就采用UTF-16编码。但是他不适合在网络之间传输,因为网络传输容易损坏字节流,一旦字节损坏将很难恢复,所以相比较而言UTF-8更适合网络传输。UTF-8对ASCII字符采用单字节存储,另外单个字符损坏也不会影响后面的其他字符,在编码效率上介于GBK和UTF-16之间,所以UTF-8在编码效率上和编码安全性上做了平滑,是理想的中文编码方式。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/81325879