文本文件的编码识别

文本文件的编码识别

文本文件的编码问题,困扰我很久,在跨平台、源程序中的中文字符、从文本文件中读取中文字符的时候,若对文件编码问题没有弄清楚,难免会走弯路。对此情况,我准备针对几个主题,记录下自己学习的心得,以备日后查阅和分享。

认识文本文件

文件分为两种类型:文本文件和二进制文件; 
文件文件:是以字符编码的方式进行保存的;每一行都以换行符结束(由于历史原因,各操作系统的换行符不一样,Windows的是"<回车><换行>",即"\r\n",Unix/Linux的是"<换行>",即"\n",Mac的是"回车",即"\r");在文件最后一行的结尾有文件结束标志EOF,它的值也依赖于系统,一般为-1。 
二进制文件:是将内存中数据原封不动的读取和写入文件中。

字符编码

一般常见的编码格式有:ASCII、UTF-8、UTF-16、GB2312、Big5、GBK、GB18030。 详细的字符编码知识,此处不再多说。

需要知道的事:

  • 在Windows的语境中,所谓的[ANSI]指的是对应当前系统 locale 的遗留(legacy)编码。
  • 在Windows的语境中,所谓的[Unicode]指的是带有 BOM 的小端序 UTF-16。
  • 在Windows的语境中,所谓的[UTF-8]指的是带 BOM 的 UTF-8。

文件编码的模式识别

知道了字符编码的细节,还不足以正确处理我们所面对的种类繁多的文本文件。 
首先,我们看看各编码格式的文件存储格式。

BOM:要识别UTF-8和UTF-16就不得不说到字节顺序标记(byte-order mark,BOM),它用来标识该字节流的字节序,是高位在前还是低位在前。从Unicode3.2开始,BOM只能位于流的开头,只能用于标识字节序。

UTF-16中,字节顺序标记被放置为文件或字符串流的第一个字符,以标示在此文件或字符串流中,以所有十六比特为单位的字码的尾序(字节顺序)。 * 如果十六比特单位被表示成大尾序,这字节顺序标记字符在串行中将呈现0xFE,其后跟着0xFF(其中的0x用来标示十六进制)。 * 如果十六比特单位使用小尾序,这个字节串行为0xFF,其后接着0xFE。

UTF-8则没有字节顺序的议题。UTF-8编码过的字节顺序标记则被用来标示它是UTF-8的文件。它只用来标示一个UTF-8的文件,而不用来说明字节顺序。 许多Windows程序(如记事本)会添加字节顺序标记到UTF-8文件。然而,在类Unix系统(大量使用文本文件,用于文件格式,用于进程间通信)中,这种作法则不被建议采用。 故,UTF-8分为UTF-8有BOM格式和UTF-8无BOM格式。

UTF-8: 若为UTF-8有BOM格式,则文件开头为 EF BB BF; 若为UTF-8无BOM格式,则不能依据上述规则;此时需要依据UTF-8编码格式来判断,其编码如下:

U-00000000 - U-0000007F: 0xxxxxxx 
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx 
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-16: 若为UTF-16(大端序),则文件开头为 FE FF; 若为UTF-16(小端序),则文件开头为 FF FE;

GB2312: GB2312中对所收汉字进行了"分区"处理,每区含有94个汉字/符号。这种表示方式也称为区位码。

  • 01-09区为特殊符号。
  • 16-55区为一级汉字,按拼音排序。
  • 56-87区为二级汉字,按部首/笔画 排序。

在使用GB2312的程序通常采用EUC储存方法,以便兼容于ASCII. 
ASCII字符,范围为0x20-0x7E,直接用单字节表示。 每个汉字及符号以两个字节来表示。第一个字节称为"高位字节",第二个字节称为"低位字节"。 "高位字节"使用了0xA1-0xF7(把01-87区的区号加上0xA0),"低位字节"使用了0xA1-0xFE(把01-94加上0xA0)。

Big5: Big5码是一套双字节字符集,使用了双八码存储方法,以两个字节来安放一个字。第一个字节称为"高位字节",第二个字节称为"低位字节"。 "高位字节"使用了0x80-0xFE,"低位字节"使用了0x40-0x7E,及0xA1-0xFE。 因Big5相对使用较少,此处不做识别。

GBK: 字符有一字节和双字节编码,00–7F范围内是一位,和ASCII保持一致,此范围内严格上说有96个文字和32个控制符号。 
之后的双字节中,前一字节是双字节的第一位。总体上说第一字节的范围是81–FE(也就是不含80和FF),第二字节的一部分领域在40–7E,其他领域在80–FE.

GB18030: 标准采用单字节、双字节和四字节三种方式对字符编码。 
使用0×00至0×7F码位(对应于ASCII码的相应码位)。 
双字节部分,首字节码位从0×81至0×FE,尾字节码位分别是0×40至0×7E和0×80至0×FE。 四字节部分采用GB/T 11383未采用的0×30到0×39作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为0×81308130到0×FE39FE39。其中第 一、三个字节编码码位均为0×81至0×FE,第二、四个字节编码码位均为0×30至0×39。

面向字节的模式识别

UTF-16 直接根据其BOM识别; 
UTF-8 首先根据BOM识别,若不符,再以上述编码规则识别; 
GB2321、GB18030 因GB18030完全兼容GB2321,则只识别GB18030,根据如下规则识别:

单字节: 0到0x7F 0000.0000-0111.1111 双字节: 第一个字节的值从0x81到0xFE,第二个字节的值从0x40到0xFE(不包括0x7F) 1000.0001-1111.1110 0100.0000-1111.1110 四字节,第一个字节的值从0x81到0xFE,第二个字节的值从0x30到0x39,第三个字节从0x81到0xFE,第四个字节从0x30到0x39 1000.0001-1111.1110 0011.0000-0011.10001 1000.0001-1111.1110 0011.0000-0011.10001

 PS:个人新干博客地址 http://www.lontoken.com/

转载于:https://www.cnblogs.com/lontoken/p/3472223.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值