BOM是UTF編碼方案裡用於標識編碼的標準標記,在UTF-16裡是FF FE,UTF-8裡是EF BB BF。這個標記是可選的,因為UTF-8沒有順序,所以它可以被用來檢測一個位元組流是否是UTF-8編碼的。微軟做這種檢測,但有些軟體不做這種檢測,而把它當做正常字元處理。
微軟在自己的UTF-8格式的文字檔之前加上了EF BB BF三個位元組, windows上面的notepad等程式就是根據這三個位元組來確定一個文字檔是ASCII的還是UTF-8的, 然而這個只是微軟暗自作的標記, 其它平台上並沒有對UTF-8文字檔做個這樣的標記,類Unix系統中就沒有使用 BOM,因為它會破壞現有的 ASCII 檔案的文法約定。也就是說一個UTF-8檔案可能有BOM,也可能沒有BOM,那麼怎麼區分呢?
三種方法:
1、用UltraEdit-32開啟檔案,切換到十六進位編輯模式,查看檔案頭部是否有EF BB BF;
2、用Dreamweaver開啟,查看頁面屬性,看“包括Unicode簽名BOM”前面是否有個勾;
3、用Windows的記事本開啟,選擇 “另存新檔”,看檔案的預設編碼是UTF-8還是ANSI,如果是ANSI則不帶BOM。
所謂的unicode儲存的檔案實際上是utf-16,只不過恰好跟unicode的碼相同而已,但在概念上unicode與 utf是兩回事,unicode是記憶體編碼錶示方案,而utf是如何儲存和傳輸unicode的方案。utf-16還分高位在前 (LE)和高位在後(BE)兩種。官方的utf編碼還有utf-32,也分LE和BE。非unicode官方的utf編碼還有utf-7,主要用於郵件傳輸。utf-8的單位元組部分是和iso-8859-1相容的,這主要是為瞭解決一些舊的系統和庫函數不能正確處理utf-16的問題,而且對英語字元來說,也節省儲存的檔案空間(以非英語字元浪費空間為代價)。在iso-8859-1的時候,utf8和iso-8859-1都是用一個位元組表示的,當表示其它字元的時候,utf-8會使用兩個或三個位元組。
匯出代碼:
public static void ExportToCSV(DataTable dt, string fileName) { StringBuilder sb = new StringBuilder(); int i = 0; for (i = 0; i <= dt.Columns.Count - 1; i++) { if (i > 0) { sb.Append(","); } sb.Append(dt.Columns[i].ColumnName); } sb.Append("\n"); foreach (DataRow dr in dt.Rows) { for (i = 0; i <= dt.Columns.Count - 1; i++) { if (i > 0) { sb.Append(","); } sb.Append(dr[i].ToString()); } sb.Append("\n"); } byte[] buffer = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); byte[] outBuffer = new byte[buffer.Length + 3]; outBuffer[0] = (byte)0xEF; outBuffer[1] = (byte)0xBB; outBuffer[2] = (byte)0xBF; Array.Copy(buffer, 0, outBuffer, 3, buffer.Length); HttpResponse rs = System.Web.HttpContext.Current.Response; rs.ContentEncoding = System.Text.Encoding.UTF8; rs.AppendHeader("Content-Disposition", "attachment;filename=" + fileName); rs.ContentType = "application/ms-excel"; rs.Write(Encoding.UTF8.GetString(outBuffer)); rs.Flush(); rs.End(); }