編碼轉換:UTF-8 BOM to GBK

編碼轉換:UTF-8 BOM to GBK

      最近由於一個實驗,須要文本文件的編碼格式爲GBK或者GB2312,而源數 據又是不少編碼格式的,有些是GBK,有些是UTF-8,這樣就很差用工具直接轉,手動就更不可取了,因而打算寫個程序,可以讀取UTF-8的文件,更改編碼後,再寫入另外一個文件,存爲GBK格式。

      在網上看了不少例子,也查了python API,發現都不完整,緣由就在於都沒考慮到有BOM和無BOM兩種狀況。也有說用codecs.EncodedFile(...)來作的,試了不少次,不管是有BOM仍是無BOM,轉成GBK都失敗。 python

      下面來看個人試驗過程。 工具

      1.無BOM的UTF-8轉GBK 測試

      首先用ultraedit新建一個文本文件,並存爲UTF-8 無BOM格式,個人叫「u8.txt」,內容爲「試 試 這 個」,帶回車換行,而且字符間加了空格,以便定位; 編碼

      其次,寫代碼測試: spa

              import codecs code

              f = open("u8.txt", "r");
              data = f.read();
              print repr(data)
              print data.decode("utf-8").encode("gbk") ip

              s = '/xe8/xbf/x99 /xe4/xb8/xaa';
              print s.decode("utf-8").encode("gbk")
              f.close(); utf-8

      運行查看結果: 字符串

             讀取utf8無BOM的文件

      根據輸出可見,第一行是4個漢字字符的UTF-8編碼,每一個字符佔3個字節,最後跟着一個換行符;第二行是編碼爲GBK後打印的結果,說明編碼轉換沒有問題;注意字符串s的內容爲我手工截取的最後兩個字符的字節編碼,即「這 個」,對s先解碼再編碼成GBK後,成功輸出。 it

      由此可知,無BOM的UTF-8轉換成GBK是很容易的。

      2.有BOM的UTF-8轉GBK

      首先,仍然用ultraedit新建一個文本文件,可是須要保存爲UTF-8,這就是有BOM的格式,個人是「char.txt」,內容爲「老 子 不 信 轉 不 過 來」,也是帶空格以便定位字符,仍然用上面的代碼運行,結果爲:

      讀取UTF8帶BOM

       出現錯誤!提示說沒法對0字節處採用GBK編碼,再看顯示出的編碼序列,發現最開頭那段6個字節連在一塊兒,可是咱們的字符串分明是按空格分開的!怎麼回事?!經過查wikipedia發現:

       BOM

       原來最開始的「/xef/xbb/xbf」是UTF-8的BOM!那是否是由於這個BOM才形成編碼轉換失敗的呢?能夠複製BOM後面的內容做爲字符串s的內容,寫代碼測試,代碼以下:

       s = '/xe8/x80/x81 /xe5/xad/x90 /xe4/xb8/x8d /xe4/xbf/xa1 /xe8/xbd/xac /xe4/xb8/x8d /xe8/xbf/x87 /xe6/x9d/xa5/n'                          

       print s.decode("utf-8").encode("gbk")
       運行後發現,轉換成功進行,這就是說,只要能在轉換前去掉BOM,那麼就能轉換成功。
       根據上面的心得,我寫了下面的代碼測試:

       代碼

       代碼說明:bom爲讀取文件前3個字節的內容,codecs.BOM_UTF8表明的就是utf8 BOM的字節編碼,前面已經提到了。if語句判斷是否爲UTF8 BOM格式,若是是,咱們就從文件的第3個字節開始讀文件,以便避開BOM,而後就是轉換,最後成功輸出。

       結果

        代碼中「注意」那行打印出字節編碼,可見,字符已被轉換成2 Bytes per character的GBK編碼格式。

 

        結束語:這裏只寫了UTF8格式的,UTF16的道理也同樣,只是UTF16的BOM只有兩個字節,具體可見上面的BOM表示的圖。總結起來講就是:UTF8轉GBK原本是很容易的,由於字符都對應,只是由於有了BOM,使問題變得麻煩些,不過弄懂了原理也不復雜

相關文章
相關標籤/搜索