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
UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。
UTF-8編碼的文件中,BOM占三個字節。如果用記事本把一個文本文件另存為UTF-8編碼方式的話,用UE打開這個文件,切換到十六進制編輯狀態就可以看到開頭的FFFE了。這是個標識UTF-8編碼文件的好辦法,軟件通過BOM來識別這個文件是否是UTF-8編碼。
對於含BOM頭的UTF8文件,前三個字節是\xEF\xBF\xBD,某些軟件對於不包含BOM頭格式的文件識別存在問題,而有些軟件對於有BOM頭的文件解析有問題。所以這個問題要區別對待,我們可以在Notepad++里進行轉換。
C#寫文件時指定是否有BOM
下面是C#在寫文件時指定BOM頭的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
var utf8WithBom =
new
System.Text.UTF8Encoding(
true
);
// 用true來指定包含bom
StreamWriter swr =
null
;
try
{
swr =
new
StreamWriter(
"okbase.txt"
,
false
, utf8WithBom);
swr.Write(
"hello okbase.net!"
);
}
catch
(Exception e)
{
}
finally
{
if
(swr !=
null
)
{
swr.Close();
swr.Dispose();
}
}
|
下面的代碼是不需要BOM:
1
2
3
4
5
|
var utf8WithoutBom =
new
System.Text.UTF8Encoding(
false
);
using
(var sink =
new
StreamWriter(
"Foobar.txt"
,
false
, utf8WithoutBom))
{
sink.WriteLine(
"..."
);
}
|