程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 【手記】注意BinaryWriter寫string的小坑——會在string前加上長度前綴length-prefixed,cbinarywriter

【手記】注意BinaryWriter寫string的小坑——會在string前加上長度前綴length-prefixed,cbinarywriter

編輯:關於.NET

【手記】注意BinaryWriter寫string的小坑——會在string前加上長度前綴length-prefixed,cbinarywriter


之前以為BinaryWriter寫string會嚴格按構造時指定的編碼(不指定則是無BOM的UTF8)寫入string的二進制,如下面的代碼:

//將字符串"a"寫入流,再拿到流的字節組data
using (var ms = new MemoryStream())
{
    using (var bw = new BinaryWriter(ms))
    {
        bw.Write("a");
    }
    byte[] data = ms.ToArray();
}

因為字母a的utf8編碼是97,所以我預期data只有1個元素且值為97,而實際上,data有兩個元素,依次為1、97,顯然97代表a,但前面的1是什麼鬼,再試其它字符串,仍然會在前面多出1個甚至多個字節,值也比較漂浮,總之就是bw並沒有原原本本的寫入string的二進制,而是加了些料,這在嚴格要求字節正確的場景會出問題,如http請求體,服務器會對這些多出來的字節表示懵逼。遂搜索一番,發現MSDN、stackoverflow早有提到,前面多出來的字節實際上是表示string的長度,叫長度前綴(length-prefixed),據SO某答主的說法,這是供BinaryReader的ReadString方法用,知道長度,它才知道要讀取到哪裡。所以如果流的讀取方不是BinaryReader,這些長度前綴就是多余甚至是有害的,這種情況下就不能使用BinaryWriter.Write(string)方法,要寫入干淨的string二進制,可以這樣:

bw.Write(Encoding.UTF8.GetBytes("a"));//按需選用正確的編碼

即先用具體編碼得到string的字節組,再用BinaryWriter.Write(byte[])寫入該字節組。

-文畢-

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved