一、測試方法是否結果相同
首先看下面兩段代碼1是StreamWriter.Write 2是Stream.Write:
1
2
上面我們可以看到StreamWriter.Write的可讀性更好一些。
但是這兩段代碼執行后的ms是否是相同的結果呢?
首先我們來看下長度吧,在代碼最后分別加上
各位看官,看到這里有何想法?
二、深究原因
下面繼續深究一下這個多出來的3個字節
在方法后面都加上如下一段代碼將MemoryStream的內容以十六進制的形式打印出來
這里我們發現用StreamWriter.Write輸出多出了EF BB BF這3個字節
Google一下:多出來的這個玩意是 字節順序記號(英語:byte-order mark,BOM)
在維基百科中可以查到:
編碼 | 表示 (十六進制) | 表示 (十進制) |
---|---|---|
UTF-8 | EF BB BF | 239 187 191 |
UTF-16(大端序) | FE FF | 254 255 |
UTF-16(小端序) | FF FE | 255 254 |
UTF-32(大端序) | 00 00 FE FF | 0 0 254 255 |
UTF-32(小端序) | FF FE 00 00 | 255 254 0 0 |
UTF-7 | 2B 2F 76和以下的一個字節:[ 38 | 39 | 2B | 2F ] | 43 47 118和以下的一個字節:[ 56 | 57 | 43 | 47 ] |
en:UTF-1 | F7 64 4C | 247 100 76 |
en:UTF-EBCDIC | DD 73 66 73 | 221 115 102 115 |
en:Standard Compression Scheme for Unicode | 0E FE FF | 14 254 255 |
en:BOCU-1 | FB EE 28 及可能跟隨著FF | 251 238 40 及可能跟隨著255 |
ok,了解了這個東西后我們就就需要知道在StreamWriter.Write中能否用代碼控制不輸出這個BOM嗎?
三、查找解決辦法
開始反編譯StreamWriter.Write這個方法:
大致猜測是紅色方框的代碼輸出了BOM信息,ok再進去看:
果然在這里,看上圖紅框處,GetPreamble方法是獲取編碼的字節序列,和我們之前查到的信息完全一致。
好下面繼續找這個haveWrittenPreamble有沒設置的可能,在Init方法中找到了它的身影。
杯具了,CanSeed沒有set方法,Write之前的Position肯定為0,至此結束。
四、結論
由上面的結論,我們可以確定:
1.如果雙方協議無BOM時,可以使用Stream.Write方法來輸出,或者使用StreamWriter.Write時加入new UTF8Encoding(false)參數。
2.有BOM時,我們可以通過GetPreamble和Stream.Write來完成StreamWriter.Write的功能。
新聞熱點
疑難解答