BOM 是什么
文本文件本质就是一串用二进制表示的字符,但是相同的字符在不同的字符编码下一般就是不同的编码,发过来一个确定的文件被用不同的字符编码来解释的话如果和原来的相同那么是 OK 的,如果不同就会出现所谓的乱码。
如果所有的地方都是用同一个编码比如 utf-8 那就不会有这个问题了(比如在类 Unix 环境下一般就是这样,所以会很和谐,基本不会出现乱码的情况)。但是实际情况是很多人用的 Windows 机器的中文环境(其他语言比如日语环境之类的暂且不说)中很多软件默认的字符编码是 GBK 的,这样如果把一个 utf-8 的文件交给它就会失败啦。
那么在 Windows 下如果想用 utf-8 要怎么办呢?那就用一下 BOM(byte-order mark 字节顺序标记)吧,在文件开头插入三个字节 EF BB BF
,这三个字节应该实际是不对应字符的,下面用 python 检查下:
>>> print '\xe4\xb8\xad\xe6\x96\x87'
中文
>>> print '\xef\xbb\xbf'
发现 EF BB BF
确实打印不出东西。本着刨根问底的态度在多走一点,不如去查一下 utf-8 的表:
确实如想象的那样!
这样的话给 utf-8 文件前面加上 BOM 的话在 Windows 下就可以正常识别了,而且也基本不会影响在类 Unix 环境下的使用(其实还是会有影响的,毕竟加了点东西进去,可能对一些产生影响,所以 BOM 这种东西能不用就不用,干净一些更好,BOM 的 Wiki 中有提到,有兴趣的可以再去调研一下)。
怎么给文件加 BOM
检查一下编码
把上面的「中文」保存到文件中,可以看出是 utf-8 编码的无误:
$ 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。
下面把后缀改成 cxv 然后用 Excel 打开试试吧!发现确实如此:
另外的解决方法
把之前的 open
替换为 codecs.open('filename', 'w', 'utf_8_sig')
:
# coding: utf-8
import codecs
with codecs.open('workfile-with-bom', 'w', 'utf_8_sig') as f:
f.write(u'中文')
这样写出的文件是自带 BOM 的。(请注意在用 codecs 的时候 u'中文'
是可以的,但是 '中文'
就不行)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。