BOM是什麼
Unicode的學名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。在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(即Byte Order Mark)。
UTF-8 BOM頭又是什麼
UTF-8以位元組為編碼單元是以不需要 BOM 來表明位元組順序,但可以用 BOM 來表明編碼方式。字元 "Zero Width No-Break Space" 的 UTF-8 編碼是 EF BB BF。是以如果接收者收到以 EF BB BF 開頭的位元組流,就知道這是 UTF-8編碼了。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yN1QTMzUDN1QTMtkDOzQjM3QTNxYTM3AjNxAjMtMzMwITN58CX3AjNxAjMvw1MzAjM1kzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
是以UTF-8編碼的字元串開頭處的三個bytes 0xef,0xbb,0xbf就稱為UTF-8 BOM頭。
為什麼excel打開沒有BOM頭的csv檔案會亂碼?
類似WINDOWS自帶的記事本等軟體,在儲存一個以UTF-8編碼的檔案時,會在檔案開始的地方插入UTF-8 BOM頭。記事本等編輯器通過它來識别這個檔案是否以UTF-8編碼(當然即便沒有UTF-8 BOM頭記事本也能通過其它方式正确識别UTF-8編碼)。
那麼如果一個UTF-8編碼的字元串的開頭處沒有BOM頭又會發生什麼?
比如我們用C#建立一個csv檔案,裡面儲存中文,日文等多國語言的字元串然後以UTF-8編碼儲存(此時沒有UTF-8 BOM頭)。
記事本能夠識别,但是excel卻識别出錯:
這是一個已知的問題,Excel打開沒有BOM頭的csv檔案時就是會這樣!
解決的辦法也很簡單,在生成字元串時手動把UTF-8 BOM頭添加在字元串的開頭處,下面是C#代碼:
sb.Append('\uFEFF');
好了,重新用Excel打開,已經可以正确識别了!
作者:sparkdev
出處:http://www.cnblogs.com/sparkdev/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。