utf-8 bom 小实验

BOM 是什么

文本文件本质就是一串用二进制表示的字符,可是相同的字符在不一样的字符编码下通常就是不一样的编码,发过来一个肯定的文件被用不一样的字符编码来解释的话若是和原来的相同那么是 OK 的,若是不一样就会出现所谓的乱码。python

若是全部的地方都是用同一个编码好比 utf-8 那就不会有这个问题了(好比在类 Unix 环境下通常就是这样,因此会很和谐,基本不会出现乱码的状况)。可是实际状况是不少人用的 Windows 机器的中文环境(其余语言好比日语环境之类的暂且不说)中不少软件默认的字符编码是 GBK 的,这样若是把一个 utf-8 的文件交给它就会失败啦。shell

那么在 Windows 下若是想用 utf-8 要怎么办呢?那就用一下 BOM(byte-order mark 字节顺序标记)吧,在文件开头插入三个字节 EF BB BF,这三个字节应该实际是不对应字符的,下面用 python 检查下:segmentfault

>>> print '\xe4\xb8\xad\xe6\x96\x87'
中文
>>> print '\xef\xbb\xbf'

发现 EF BB BF 确实打印不出东西。本着刨根问底的态度在多走一点,不如去查一下 utf-8 的表编码

bom

确实如想象的那样!spa

这样的话给 utf-8 文件前面加上 BOM 的话在 Windows 下就能够正常识别了,并且也基本不会影响在类 Unix 环境下的使用(其实仍是会有影响的,毕竟加了点东西进去,可能对一些产生影响,因此 BOM 这种东西能不用就不用,干净一些更好,BOM 的 Wiki 中有提到,有兴趣的能够再去调研一下)。code

怎么给文件加 BOM

检查一下编码

把上面的「中文」保存到文件中,能够看出是 utf-8 编码的无误:blog

$ cat hello-chinese.py
# coding: utf-8

print '\xe4\xb8\xad\xe6\x96\x87'
$ python hello-chinese.py > hello-chinese.txt
$ cat hello-chinese.txt
中文
$ hexdump hello-chinese.txt
0000000 e4 b8 ad e6 96 87 0a

用最朴素的方法加上 BOM

$ cat hello-chinese-with-bom.py
# coding: utf-8

print '\xef\xbb\xbf\xe4\xb8\xad\xe6\x96\x87'
$ cat hello-chinese-with-bom.txt
中文
$ hexdump hello-chinese-with-bom.txt
0000000 ef bb bf e4 b8 ad e6 96 87 0a

若是是用 open 的方式打开文件,那么能够在最开始的位置 f.write('\xef\xbb\xbf') 来加上 BOM。ip

下面把后缀改为 cxv 而后用 Excel 打开试试吧!发现确实如此:utf-8

hello-chinese
hello-chinese-with-bom

另外的解决方法

把以前的 open 替换为 codecs.open('filename', 'w', 'utf_8_sig')unicode

# coding: utf-8
import codecs

with codecs.open('workfile-with-bom', 'w', 'utf_8_sig') as f:
    f.write(u'中文')

这样写出的文件是自带 BOM 的。(请注意在用 codecs 的时候 u'中文' 是能够的,可是 '中文' 就不行)

参考资料

相关文章
相关标签/搜索