C# 使用 UTF8 編碼輸出文字 (包含 EF BB BF 詳細測試)

TL;DR;

File.WriteAllText 輸出 UTF8 編碼格式
    
File.WriteAllText("text1.txt", "Ruyut的部落格", Encoding.UTF8); // UTF8, 有 BOM
File.WriteAllText("text2.txt", "Ruyut的部落格", new UTF8Encoding(false)); // UTF8, 無 BOM
    

StreamWriter 輸出 UTF8 編碼格式
    
// UTF8, 有 BOM
using (StreamWriter sw = new StreamWriter("text3.txt", false, Encoding.UTF8))
{
    sw.WriteLine("Ruyut的部落格");
}

// UTF8, 無 BOM
using (StreamWriter sw = new StreamWriter("text4.txt", false, new UTF8Encoding(false)))
{
    sw.WriteLine("Ruyut的部落格");
}
    

說明

在輸出資料時,如果把編碼格式設定成 UTF-8,通常檔案會被自動加上三組 16 進制的字元:0xEF 0xBB 0xBF
他叫做「位元組順序記號」,英文是 BOM,其目的是讓檔案開啟時,編碼自動被辨識為 UTF-8。

依據維基百科的說明:在UTF-8中,雖然在 Unicode 標準上允許位元組順序記號的存在,但實際上並不一定需要,且有時候會造成很大的困擾

有一次筆者把檔案匯入資料庫中,第一個欄位長度設定為6,查詢的時候發現怎麼有幾筆資料怪怪的,後來才發現是因為原本的資料被 BOM 擠掉了,造成資料匯入錯誤

測試

為了瞭解什麼情況下會產生 BOM 和 中英文的輸出是否會造成影響,所以才會有本次測試

測試內容:

筆者將 「預設輸出」、「UTF8」、「 UTF8 無 BOM 」的三種分別使用 File.Write 和 StreamWriter 這兩種輸出方式,各輸出中英文一次

測試環境:

 作業系統: Windows 11
 語言版本: C# 10
 框架: .NET Core 6

英文輸出內容: Ruyut.com
中文輸出內容: Ruyut的部落格

File.Write:

StreamWriter:


結論

在 .NET Core 6 中預設就是 UTF-8 無 BOM ,所以不用再手動指定編碼格式,指定 UTF-8 反而還會留下 EF BB BF

不過為了保證安全,筆者建議在實際正式環境中還是不要冒這個險,多寫半行程式以策安全。

留言