1. 程式人生 > >UTF-8與UTF-8 without BOM

UTF-8與UTF-8 without BOM

UTF-8編碼的檔案可以分為without BOM和BOM兩種格式。

何謂BOM? “EF BB BF” 這三個位元組就叫BOM,BOM的全稱叫做"Byte Order Mark". 在UTF-8檔案中常用BOM來表明這個檔案是UTF-8檔案, 而BOM的本意是在UTF-16中用來表示高低位元組序列的。在位元組流之前有BOM表示採用低位元組序列(低位元組在前面),而UTF-8不用考慮位元組序列,所以其實有無BOM都可以。UTF-8以位元組為編碼單元,沒有位元組序的問題。UTF-16以兩個位元組為編碼單元,在解釋一個UTF-16文字前,首先要弄清楚每個編碼單元的位元組序。例如收到一個“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16位元組流“594E”,那麼這是 “奎”還是“乙”?

如果檔案儲存時,選擇了使用BOM,那麼就可能會出現headers already sent的問題。
因為Web伺服器軟體可能不認識BOM,所以就把BOM的兩個特殊位元組當做字元傳送給瀏覽器了。
這時再呼叫session_start()等函式,就會出現headers already sent的問題。
所以解決此問題最根本的方法就是在儲存UTF-8編碼的檔案時,不要使用BOM。

微軟的記事本Word等只能正確開啟含BOM的UTF8檔案,然而UltraEdit卻恰恰相反,會把BOM UTF-8檔案誤認為ascii編碼。
UTF-8的BOM是 EFBBBF,因為UE載入UTF-8檔案會轉成Utf16,上述的EFBBBF 在Utf16中是FFFE(Unicode-LE的BOM),UltraEdit不認識BOM又加多一個BOM,所以有2個FFFE。檔案就被它破壞了。

當應用程式的檔案使用 UTF8 編碼時,在儲存檔案時,一定要注意 BOM 的問題。那麼如何將UTF8 without BOM轉換成UTF8呢?

using (TextReader input = new StreamReader(new FileStream(@"C:\Test.properties", FileMode.Open), Encoding.UTF8))
{
    using (TextWriter output = new StreamWriter(new FileStream(@"C:\Test2.lmx", FileMode.Create), Encoding.UTF8))
    {
        int BufferSize = 8096;
        char[] buffer = new char[i];
        int len;
 
        while ((len = input.Read(buffer, 0, i)) > 0)
        {
            output.Write(buffer, 0, len);
        }
 
        input.Close();
    }
}