簡體   English   中英

C# BinaryWriter 寫入方法字符串大小

[英]C# BinaryWriter Write Method String Size

使用 C# 將字符串寫入二進制文件時,長度(以字節為單位)會自動添加到輸出中。 根據MSDN 文檔,這是一個無符號整數,但也是一個字節。 他們給出的示例是單個 UTF-8 字符將是三個寫入字節:1 個大小字節和 2 個字符字節。 這對於長度不超過 255 的字符串很好,並且與我觀察到的行為相匹配。

但是,如果您的字符串長於 255 個字節,則無符號整數的大小會根據需要增加。 作為一個簡單的例子,將 1024 個字符視為:

string header = "ABCDEFGHIJKLMNOP";
for (int ii = 0; ii < 63; ii++)
{
  header += "ABCDEFGHIJKLMNOP";
}
fileObject.Write(header);

導致字符串前有 2 個字節。 創建一個 2^17 長度的字符串會導致一個有點令人抓狂的 3 字節數組。

因此,問題是如何知道讀取多少字節才能獲得讀取時的大小? 我不一定先驗地知道標題大小。 最終,我是否可以強制 Write(string) 方法始終使用一致的大小(比如 2 個字節)?

一種可能的解決方法是編寫我自己的 write(string) 方法,但出於明顯的原因,我想避免這種情況( 此處此處的類似問題接受此作為答案)。 另一個更可口的解決方法是讓讀者查找開始 ASCII 字符串信息的特定字符(可能是不可打印的字符?),但這並非萬無一失。 最后的解決方法(我能想到的)是強制字符串在特定大小字節數的大小范圍內; 再一次,這不是理想的。

雖然強制字節數組的大小保持一致是最簡單的,但我可以控制讀取器,因此也歡迎任何聰明的讀取器解決方案。

BinaryWriterBinaryReader不是寫入二進制數據的唯一方法; 很簡單:它們提供特定讀者和作者之間共享的約定 不,您不能告訴他們使用其他約定 - 除非您當然對它們進行子類化並完全覆蓋ReadStringWrite(string)方法。

如果您想使用不同的約定,那么只需:不要使用BinaryReaderBinaryWriter 使用您想要獲取字節和字節數的任何文本Encoding直接與Stream對話非常容易。 然后你可以使用任何你想要的約定 如果您只需要寫入最多 65k 的字符串,那么請確保:使用固定的 2 個字節(無符號短整型)。 當然,您還需要決定哪個字節先出現(“字節序”)。

至於前綴的大小:它本質上是使用:

int byteCount = this._encoding.GetByteCount(value);
this.Write7BitEncodedInt(byteCount);

與:

protected void Write7BitEncodedInt(int value)
{
    uint num = (uint) value;
    while (num >= 0x80)
    {
        this.Write((byte) (num | 0x80));
        num = num >> 7;
    }
    this.Write((byte) num);
}

這種類型的長度編碼非常常見 - 例如,它與“protobuf”使用“varint”的想法相同(base-128,最低有效組在前,在 7 位組中保留位順序,第 8 位為續)

如果你想自己寫長度:

using (var bw = new BinaryWriter(fs))
{
  bw.Write(length); // Use a byte, a short...
  bw.Write(Encoding.Unicode.GetBytes("Your string"));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM