首页 > 代码库 > 文件的编码是一个怎样的机制

文件的编码是一个怎样的机制

比如我在mac上有个f.txt文件,系统是utf-8编码其中有数据 "\xE6\x97\A5"——在utf-8编码下为汉字"日"

那么我用ultraedit将f.txt另存为以下几个文件:

  1. f1.txt文件其实际存储的内容为"\xE6\x97\A5",让ultraedit将其解释为是gb18030编码,那么在ultraedit界面显示为乱码。之后另存为gb18030编码的文件,在mac系统打开却是utf-8,显示正常的。

  2. f2.txt文件实际存储内容为"\xE6\x97\A5",解释为utf-8,那么显示为"日"

  3. f3.txt文件直接另存为gb18030编码,那么ultraedit会自动改变编码 即把"\xE6\x97\A5"变为"\xC8\xD5"。之后vim打开文件调用ascii编码解释。

问题来了,
既然实际存储数据是"\xE6\x97\A5",那我的编辑器凭什么解释为utf-8编码呢?我想得到GBK解释的乱码怎么办?
是在文档的二进制头部加入某种标记吗,如果是,这种标记该如何查看?
是在编辑器端进行基于编码的语义分析吗?

1

就拿 vim 来说吧

一个文本文件,vim 打开的时候按某种编码A打开,转换成某种编码B,然后保存的时候转换成另一种编码C,其他文本编辑器类似,可能没有vim这么可以设置和自动完成。编码B:对于整个文件没有影响,只是事关显示的,就是vim与操作系统交互时候使用的编码。

编码A:使用 set fileencodings=ucs-bom,utf-8,gbk,cp936,latin-1设置。vim 按照设置的顺序检查检测文件的编码。因为某些编码里不存在某些二进制序列的组合,所以如果检测到就认为不是这种编码,检查下一种编码,否则就认为是这一种。因为latin-1可以出现任何二进制序列的组合,所以如果放到第一个,那么将永远以latin-1显示。

在一般的二进制文件里是不存在字符编码的标记的。但是Unicode里面有个特殊叫做零宽度空格(\FE\FF)而\FF\FE是不存在的编码,所以在Unicode的标准里可以人为的在开始加入这个字符(这个字符在任何字体下都是没有宽度的,在中文字符里面没有任何的效果跟没有一样,是为了照顾东南亚某些语言的显示而设置的)。这样就便于文本编辑器检查字符和字节顺序,但是在代码里include这种文件经常会出问题(这可是个大坑,编译器会认为这是一个非法字符,可是你又看不到)。

编码Bset fileencoding=utf-8,保存时候使用的编码,保存的时候自动转换为另一种编码。但是如果一开始打开的时候就识别错了编码,再转换的时候一个不存在的字符也是不会完转换的。

所以 f1.txt 另存为 gp18030 可能不会进行编码的转换。

”问题来了,我想要得到实际存储数据是"\xE6\x97\A5",但是用gb18030编码解释,该如何做?“ 这个是什么意思?

 

2

 

文件编码就是实际以何种方式存储的代码规定,首先就回答你的问题,UTF8编码中是\xE6\x97\A5,你就不可能说采用GB18030编码结果还为\xE6\x97\A5字。

编辑器识别文本文件编码有不同的方式,有的文件编码带有Magic头,可以直接识别其前几个字节来完成,不过大部分文本文件不带有此类识别码,完全靠编辑器通过上下文和使用者的语言环境进行猜测。

文件的编码是一个怎样的机制