c#去bom頭

C#中,當使用帶有BOM頭的UTF-8編碼的字符串時,一定要注意。

1如果該字符串用作路徑,用來尋址。一定會出錯。
2)轉換格式時,也很容易出錯。例如字符串轉int就一定會出錯。

 

待續

 

 

————————————————————————————————————————————————

———————————————————————————————————————————————— 

 

什麼是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是在文件的開始加了幾個字節作爲標記。有了這個標記,一些協議和系統才能識別。

 

源文檔 <http://www.cnblogs.com/DDark/archive/2011/11/28/2266085.html>

————————————————————————————————————————————————————————

————————————————————————————————————————————————————————

 

由於UTF8中的BOM頭是可有可無的,又由於其BOM頭會對數據造成影響,所以去BOM頭顯得十分必要。 下面的方法可以直接對內存中的字節數組進行操作,忽略BOM頭將其轉string類型。

  public static string GetUTF8String(byte[] buffer)
        {
            if (buffer == null)
                return null;

            if (buffer.Length <= 3)
            {
                return Encoding.UTF8.GetString(buffer);
            }

            byte[] bomBuffer = new byte[] { 0xef, 0xbb, 0xbf };

            if (buffer[0] == bomBuffer[0]
                && buffer[1] == bomBuffer[1]
                && buffer[2] == bomBuffer[2])
            {
                return new UTF8Encoding(false).GetString(buffer, 3, buffer.Length - 3);
            }

            return Encoding.UTF8.GetString(buffer);
        }


當然在讀取文件時,利用 new UTF8Encoding(false) 忽略BOM頭也是可以的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章