[英]Encoding a long to a VLQ byte array and writing it to System.IO.BinaryWriter
[英]Difference in writing string vs. char array with System.IO.BinaryWriter
我正在用C#將文本寫入二進制文件,並看到寫入字符串和字符數組之間的數量差異。 我正在使用System.IO.BinaryWriter並在寫入時觀察BinaryWriter.BaseStream.Length。 這些是我的結果:
using(BinaryWriter bw = new BinaryWriter(File.Open(“data.dat”), Encoding.ASCII))
{
string value = “Foo”;
// Writes 4 bytes
bw.Write(value);
// Writes 3 bytes
bw.Write(value.ToCharArray());
}
我不明白為什么當我只寫3個ASCII字符時,字符串重載會寫入4個字節。 有誰能解釋一下?
BinaryWriter.Write(string)
的文檔聲明它將一個長度為前綴的字符串寫入此流。 Write(char[])
的重載沒有這樣的前綴。
在我看來,額外的數據是長度。
編輯:
只是為了更明確一點,使用Reflector。 您將看到它作為Write(string)
方法的一部分在那里有這段代碼:
this.Write7BitEncodedInt(byteCount);
這是一種使用盡可能少的字節數對整數進行編碼的方法。 對於短字符串(我們將每天使用少於128個字符),它可以使用一個字節表示。 對於更長的字符串,它開始使用更多字節。
以下是您感興趣的函數代碼:
protected void Write7BitEncodedInt(int value)
{
uint num = (uint) value;
while (num >= 0x80)
{
this.Write((byte) (num | 0x80));
num = num >> 7;
}
this.Write((byte) num);
}
在使用此編碼為長度添加前綴后,它會以所需的編碼寫入字符的字節。
從BinaryWriter.Write(string)
docs :
在BinaryWriter的當前編碼中將長度加前綴的字符串寫入此流,並根據使用的編碼和寫入流的特定字符推進流的當前位置。
這種行為可能是這樣的,當使用BinaryReader
讀回文件時,可以識別字符串。 (例如, 3Foo3Bar6Foobar
可以解析為字符串“Foo”,“Bar”和“Foobar”,但FooBarFoobar
不能。)實際上, BinaryReader.ReadString
正好使用此信息從二進制文件中讀取string
。
從BinaryWriter.Write(char[])
docs :
將字符數組寫入當前流,並根據使用的編碼和寫入流的特定字符推進流的當前位置。
很難誇大MSDN上文檔的全面性和實用性。 始終先檢查它們。
如前所述,BinaryWriter.Write(String)在寫入字符串本身之前將字符串的長度寫入流。
這允許BinaryReader.ReadString()知道字符串的長度。
using (BinaryReader br = new BinaryReader(File.OpenRead("data.dat")))
{
string foo1 = br.ReadString();
char[] foo2 = br.ReadChars(3);
}
你看過實際寫的是什么嗎? 我猜一個空終結器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.