分享

存文本文件及其字符编码

 子午天地 2014-05-04

网上也有许多关于纯文本的讨论,如果在搜索“乱码”,更是不尽其数。如果你开始命令行,开始编码,开始数据分析,开始操作中文,存文本及其字符编码便是最基础的东西。而往往基础的东西,真正弄懂更为不易,而或者你已经有了多年相关的经验,也不一定搞清楚了。

什么是存文本文件?

存文本由可打印字符组成,人可以直接阅读和理解其形式。

纯文本并非意味着文本是无结构的,HTML、SGML、XML等都是有良好结构定义的存文本,与直接的二进制编码相比,纯文本所处的层面往往更高。大多数二进制格式的问题在于,理解数据所必须的语境与数据本身是分离的,没有应用逻辑对其进行解释,这些数据绝对没有意义,但是通过存文本,可以获得自描述的、不依赖创建它的应用的数据流。对于大多数二进制文件,要成功的进行解析,你必须了解整个格式的所有细节。

缺点:

  • 与压缩的二进制格式相比,存储纯文本所需空间更多
  • 要解释与处理纯文本文件,计算上的代价可能更昂贵

优点:

  • 保证不过时,KEEP KNOWLEDGE IN PLAIN TEXT.
  • 更易于测试

各种声音

有关于纯文本文件的各种声音,是不同角度,不同前提对于其的描述
  • 与纯文本对应的是二进制文件
  • 纯文本文件是一种特殊的二进制文件,其可以直接转义成可读的字符
  • 由于字符编码方式的不同,纯文本的底层表示也不尽相同
  • 纯文本可由文本编辑器、或者命令直接读取,二进制也可以
  • 字符文件就是文本文件
  • 纯文本文件只包含可显示的ASCII字符
  • At a generic level of description, there are two kinds of computer files: text files and binary files.
  • 只要该文件内容的每个字节都是ASCII码,或者说,只要构成文件内容的每一个字节的高位都是0的话,这个文件就是纯文本文件
  • 在计算机文件系统中”主要功能”是用于存储文字编码信息的文件叫文本文件.信息必须包括:文字存储(哪种编码不论),其他辅助信息包括:文字图表显示控制,打印脚本,多媒体信息等
  • 在计算机文件系统中”只”是用于存储文字编码信息的文件叫纯文本文件,它只包含了文字编码,而不包括文字控制信息和其他媒体信息.
  • A plain text file is a type of file. Files can either be binary (machine code) or plain text (English or native language).
  •  Plain text, as you might have guessed, is rather plain. It supports standard ASCII characters, including numbers, symbols, and spaces, but does not support any type of text formatting.
  • You can use a basic text editor such as Notepad or WordPad (for Windows) or TextEdit (for Mac) to create a plain text document. Other word processing programs can also create plain text documents, but you may have to use the “Save As…” command and choose the plain text option when saving the file.
  • Plain text is a pure sequence of character codes; plain Unicode-encoded text is therefore a sequence of Unicode character codes.

文件构成的要素

  • 文件名
  • 类型 xml,html,txt,bat, c, ini, php, pl, js, css, fasta, fastq
  • 格式 ANSI/ASCII,UTF-8,UTF-8(no BOM),UTF-16,Unicode
  • 换行符,win CR/LF mac CR Unix LF

结论

计算机的一切,到底都是二进制的,所以文本文件是一种特殊的二进制文件,特殊在于这些二进制都对应字符编码,可以容易的进行各种操作。

——2013年5月15日

格式或者编码格式及其字符集

最重要或者最难理解的就是其编码格式,计算机中最小的操作单位是字节(Byte),通常每8位(bit)组成一个字节,1KB=1024Byte=1024*8bit,二进制也就是由0和1组成的串,为了书写或者表示的方便,通常用16进制来表示二进制,如下表格:

0000 0001 0010 0011 0100 0101 0110 0111
0 1 2 3 4 5 6 7
1000 1001 1010 1011 1100 1101 1110 1111
8 9 A B C D E F

一个字节可以用两位的十六进制表示,00~FF,共256位0~255。下表是二进制的位数,可以表示的字符数目。

2^0 2^1 2^2 2^3 2^4 2^5 2^6 2^7 2^8 2^9 2^10
0 2 4 8 16 32 64 128 256 512 1024

二进制如何表示字符,也就是编码格式标准制定的缘由。总的来讲,编码可以分为两类:

  1. Unicode,统一码、万国码、单一码,世界码,旨在全球建立统一标准
  2. ANSI,可以理解为国标,美国的ASCII,中国的GB2312,Big5,欧洲的Latin等,多了去了

Unicode

Unicode is a computing industry standard for the consistent encoding, representation and handling of text expressed in most of the world’s writing systems.

在表示一个Unicode的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。Unicode的实现方式不同于编码方式。一个字符的Unicode编码是确定的。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。

目前通用的实现方式是UTF-16小端序(LE)、UTF-16大端序(BE)和UTF-8。在Windows 附带的记事本(Notepad)中,“另存为”对话框可以选择的四种编码方式除去非Unicode编码的ANSI(对于英文系统即ASCII编码,中文系统则为GB2312或Big5编码) 外,其余三种为“Unicode”(对应UTF-16 LE)、“Unicode big endian”(对应UTF-16 BE)和“UTF-8”。

UTF-8是UNICODE的一种变长字符编码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。

从Unicode到UTF-8的编码方式如下:

Unicode编码(16进制)  UTF-8 字节流(二进制)
000000 – 00007F 0xxxxxxx
000080 – 0007FF 110xxxxx 10xxxxxx
000800 – 00FFFF 1110xxxx 10xxxxxx 10xxxxxx
010000 – 10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0×00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicode的最大码位0x10FFFF也只有21位。

例如:“汉”字的Unicode编码是0x6C49。0x6C49在0×0800-0xFFFF之间,使用用3字节 模板了:1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

ANSI

对于ANSI编码方式,存在不同的字符集(Charset), 要正确解析一个ANSI字符串,还要选择正确的字符集,每个字符集都有一个唯一的编号,称为代码页(Code Page)。简体中文(GB2312)的代码页为936,而系统默认字符集的代码页为0,它表示根据系统的语言设置来选择一个合适的字符集。

汉字编码

汉字编码中现在主要用到的有三类,包括GBK,GB2312和Big5。

  • GB2312又称国标码GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。GB2312中汉字的编码范围为,第一字节0xB0-0xF7(对应十进制为176-247),第二个字节0xA0-0xFE(对应十进制为160-254)。
  • Big5又称大五码,主要为香港与台湾使用,即是一个繁体字编码。每个汉字由两个字节构成,第一个字节的范围从0X81-0XFE(即129-255),共126种。第二个字节的范围不连续,分别为0X40-0X7E(即64-126),0XA1-0XFE(即161-254),共157种。
  • GBK是GB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。GBK中每个汉字仍然包含两个字节,第一个字节的范围是0×81-0xFE(即129-254),第二个字节的范围是0×40-0xFE(即64-254)。GBK中有码位23940个,包含汉字21003个。
 R.C.   GB   Uni. UTF-8  R.C.   GB   Uni. UTF-8
 1601 啊 B0A1 554A E5958A 1602 阿 B0A2 963F E998BF
 1603 埃 B0A3 57C3 E59F83 1604 挨 B0A4 6328 E68CA8
 1605 哎 B0A5 54CE E5938E 1606 唉 B0A6 5509 E59489
 1607 哀 B0A7 54C0 E59380 1608 皑 B0A8 7691 E79A91
 1609 癌 B0A9 764C E7998C 1610 蔼 B0AA 853C E894BC
 1611 矮 B0AB 77EE E79FAE 1612 艾 B0AC 827E E889BE
 1613 碍 B0AD 788D E7A28D 1614 爱 B0AE 7231 E788B1

ASCII

ASCII使用一个字节的其中7位二进制数来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。
ASCII编码表

如何判断是文本文件及其编码?

如前所述,每种编码都有一种规范,如果按照编码方式,能将其全部读为字符串,就是文本文件。由于编码方式的差异,程序是很容易通过判断,来知道其编码方式,如果都不行,那就是二进制了。

另外还有一种方式,BOM,Windows就是使用BOM来标记文本文件的编码方式的操作系统。什么是BOM, 标准 FAQ 中对此问题有一个专门的描述:http://www./International/questions/qa-utf8-bom,具体如下:

在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输 字符”ZERO WIDTH NO-BREAK SPACE”。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

各种系统、工具,对于BOM处理也不一样:

  • notepad:可以自动识别出没有带 bom的 utf-8 编码格式文件,但不可以控制保存文件时是否添加 bom , 如果保存文件,那么会统一添加 bom ;
  • editplus:不能自动识别出没有 bom 的 utf-8 编码格式文件,文件保存时,选择UTF-8 格式,不会在文件头写上 BOM header;
  • UltraEdit : 对于字符编码的功能最为强大, 可以自动识别带 bom 和不带 bom 的 utf-8 文件(可以配置) ; 保存的时候可以通过配置选择是否添加 bom;
  • Notepad ++ :对于 utf-8 bom 支持比较好;
  • Dreamweaver:可以配置参数,使新建文件时不写入BOM,具体如下:选择 编辑->首选参数,打开后点击左边”新建文档” 这里有个”包括Unicode 签名(BOM)” 前面的对钩去掉即可;
  • perl中输出print OUT “\x{feff}”;
  • PHP可以对BOM无视;
  •  ie 载入 utf-8 格式的文件如果不带 bom ,则会有奇异问题(缓存情况下的动态加载报错)【没有验证】
  • 做不同格式转换时,最好检测是否有bom,将其去掉,再进行转换,否则就会看到“锘”开头的乱码

还有什么?

  • Unicode是将来的趋势,各种编程语言、系统、工具都以支持Unicode为其特性;
  • DOS不支持UTF-8,UTF-8脚本的调试,是一件烦人的事情,或者不要用中文;
  • 为什么要知道这些?

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多