文本文件本質就是一串用二進制表示的字符,可是相同的字符在不一樣的字符編碼下通常就是不一樣的編碼,發過來一個肯定的文件被用不一樣的字符編碼來解釋的話若是和原來的相同那麼是 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 的表:編碼
確實如想象的那樣!spa
這樣的話給 utf-8 文件前面加上 BOM 的話在 Windows 下就能夠正常識別了,並且也基本不會影響在類 Unix 環境下的使用(其實仍是會有影響的,畢竟加了點東西進去,可能對一些產生影響,因此 BOM 這種東西能不用就不用,乾淨一些更好,BOM 的 Wiki 中有提到,有興趣的能夠再去調研一下)。code
把上面的「中文」保存到文件中,能夠看出是 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
$ 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
把以前的 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'中文'
是能夠的,可是 '中文'
就不行)