精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
UTF8 BOM產生問題與小結

寫python腳本的時候發現這樣一個問題:從xls文件導出到txt時,無法直接轉換為int型數據,輸出查看發現和文件編碼方式產生的附加信息有關用一個簡單的文件舉例

90905

90907

90908

90909

90939

90940

90946

90959

90961

90965

當文件分別用ascii,utf8,utf8 bom作為編碼格式時,顯示輸出結果如下:

使用ascii編碼的輸出:

['90905\r\n', '90907\r\n', '90908\r\n', '90909\r\n', '90939\r\n', '90940\r\n', '90946\r\n', '90959\r\n', '90961\r\n', '90965']

使用utf8編碼的輸出:

['90905\r\n', '90907\r\n', '90908\r\n', '90909\r\n', '90939\r\n', '90940\r\n', '90946\r\n', '90959\r\n', '90961\r\n', '90965']

使用bom編碼的輸出:

['\xef\xbb\xbf90905\r\n', '90907\r\n', '90908\r\n', '90909\r\n', '90939\r\n', '90940\r\n', '90946\r\n', '90959\r\n', '90961\r\n', '90965']

原來utf8 bom不能直接轉換int的原因在這里,它在文件頭插入了一個表示文件編碼的信息\xef\xbb\xbf,那么UTF-8(無BOM)和UTF-8這兩個有什么區別呢?BOM是什么呢?

什么是BOM?

BOM: Byte Order Mark

UTF-8 BOM又叫UTF-8 簽名,其實UTF-8 的BOM對UFT-8沒有作用,是為了支持UTF-16,UTF-32才加上的

BOM,BOM簽名的意思就是告訴編輯器當前文件采用何種編碼,方便編輯器識別,但是BOM雖然在編輯器中不顯示,但是會產生輸出,就像多了一個空行。

Byte Order Marks are special characters at the beginning of a Unicode file to indicate whether it is big or little endian, in other words does the high or low order byte come first. These codes also tell whether the encoding is 8, 16 or 32 bit. You can recognise Unicode files by their starting byte order marks, and by the way Unicode-16 files are half zeroes and Unicode-32 files are three-quarters zeros. Unicode Endian Markers

Byte-order mark Description
EF BB BF UTF-8
FF FE UTF-16 aka UCS-2, little endian
FE FF UTF-16 aka UCS-2, big endian
00 00 FF FE UTF-32 aka UCS-4, little endian.
00 00 FE FF UTF-32 aka UCS-4, big-endian.

UTF的字節序和BOM

UTF-8以字節為編碼單元,沒有字節序的問題。UTF-16以兩個字節為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的字節序。例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節流“594E”,那么這是“奎”還是“乙”?

Unicode規范中推薦的標記字節順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:

在UCS編碼中有一個叫做'ZERO WIDTH NO-BREAK SPACE'的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符'ZERO WIDTH NO-BREAK SPACE'。

這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little-Endian的。因此字符'ZERO WIDTH NO-BREAK SPACE'又被稱作BOM。

UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符'ZERO WIDTH NO-BREAK SPACE'的UTF-8編碼是EF BB BF。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。

Windows就是使用BOM來標記文本文件的編碼方式的。

原來BOM是在文件的開始加了幾個字節作為標記。有了這個標記,一些協議和系統才能識別。

ok,說了這么多背景,那么如何解決這個問題呢?

如何使用BOM頭

BOM頭的刪除

對UTF-16, Python將BOM解碼為空字串。然而對UTF-8, BOM被解碼為一個字符,如例:

>>> codecs.BOM_UTF16.decode( 'utf16' )  u''  >>> codecs.BOM_UTF8.decode( 'utf8' )  u'\ufeff'

簡單的做法是在文件讀入時使用

import codecsf = codecs.open(sys.argv[1],'r', 'utf_8_sig')

即可,具體可以參見[http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig|http://docs.python.org/library/codecs.html#module-encodings.utf_8_sig]

或者:

u.lstrip( unicode( codecs.BOM_UTF8, 'utf8' ) )
BOM頭的添加
out = file( 'someFile', 'w' )out.write( codecs.BOM_UTF8 )out.write( unicodeString.encode( 'utf-8' ) )out.close()out = file( 'someFile', 'w' )out.write( codecs.BOM_UTF8 )out.write( unicodeString.encode( 'utf-8' ) )out.close()

詳細的過程解釋可以參見[http://mindprod.com/jgloss/encoding.html|http://mindprod.com/jgloss/encoding.html]

參考資料:

[http://blog.sina.com.cn/s/blog_3e9d2b350100as0b.html|http://blog.sina.com.cn/s/blog_3e9d2b350100as0b.html]

[http://4nail.iteye.com/blog/840612|http://4nail.iteye.com/blog/840612]

本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
UNICODE
談談Unicode編碼,簡要解釋UCS、UTF、BMP、BOM等名詞
unicode、ucs-2、ucs-4、utf-16、utf-32、utf-8 - 歷史的...
編碼匯總整理
UTF-8 GBK UTF8 GB2312 之間的區別和關系 | 前端設計交流 - Ded...
編碼又見編碼
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 喀喇沁旗| 博野县| 黄陵县| 开江县| 浮梁县| 新晃| 昌吉市| 汝城县| 青龙| 泰州市| 宜城市| 临泽县| 正宁县| 石楼县| 呼伦贝尔市| 满城县| 铜山县| 内黄县| 蕉岭县| 白朗县| 兰州市| 门头沟区| 台中市| 南开区| 吉隆县| 两当县| 云浮市| 阜南县| 衢州市| 靖安县| 金寨县| 洮南市| 尚志市| 敦化市| 竹北市| 什邡市| 新乡市| 万全县| 昭苏县| 随州市| 凌源市|