簡體   English   中英

如何確定 BinaryWriter 寫入 memory 需要多少字節?

[英]How to determine how many bytes a BinaryWriter would take to write into memory?

我紅色: 一個字符串會占用多少字節? 以及如何知道字符串的大小(以字節為單位)? 和其他一些,但我無法計算出使用 BinaryWriter 通過 MemoryMappedViewStream 通過 MemoryMappedFile 將字符串放入 memory 的確切字節數。

有時取的長度是字符串長度+1,有時是字符串長度+2???

我都試過了:

  • System.Text.ASCIIEncoding.Default.GetByteCount(str)
  • System.Text.ASCIIEncoding.Unicode.GetByteCount(str)

但它們都不起作用。 我嘗試了字符串長度加上固定數量,但它也不起作用。

如果我檢查 BinaryWriter.BaseStream.Position 之前和之后之間的差異,那么我無法確定一種方法來確定為字符串寫入的確切字節數(之后的位置 - position 之前)。 聽起來好像有 alignment 或其他我無法弄清楚的東西?

如何每次寫入適當數量的字節?

更新

我現在使用Encoding.UTF8.GetByteCount(str) + 1; ,這在大多數情況下給了我幾乎正確的尺寸,但並非總是如此。

我根據https://referencesource.microsoft.com/#mscorlib/system/io/binarywriter.cs,08f2e8c389fd32df的 Microsoft BinaryWriter 的源代碼找到了我的答案

注意:字符串的長度寫在字符串之前,並以 7 位編碼,其中大小可能因字符串大小而異(>= 128、>=2^14、> 2^21)。

代碼:

    public static int GetBinaryWriterSizeRequired(this string str, Encoding encoding)
    {
        encoding = encoding ?? Encoding.Default;

        int byteCount = encoding.GetByteCount(str);
        int byteCountRequiredToWriteTheSize = 1;

        // EO: This code is based on the Microsoft Source Code of the BinaryWriter at:
        // https://referencesource.microsoft.com/#mscorlib/system/io/binarywriter.cs,2daa1d14ff1877bd
        uint v = (uint)byteCount;   // support negative numbers
        while (v >= 0x80)
        {
            v >>= 7;
            byteCountRequiredToWriteTheSize++;
        }

        return byteCountRequiredToWriteTheSize + byteCount;
    }

來電:

...
_writer = new BinaryWriter(_stream);
_writerEncoding = _writer.GetPrivateFieldValue<Encoding>("_encoding");
...
int sizeRequired = name.GetBinaryWriterSizeRequired(_writerEncoding);

其他(我知道我們不應該調用私有字段,但我做到了):

public static T GetPrivateFieldValue<T>(this object obj, string propName)
{
    if (obj == null)
        throw new ArgumentNullException("obj");

    Type t = obj.GetType();
    FieldInfo fi = null;
    while (fi == null && t != null)
    {
        fi = t.GetField(propName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        t = t.BaseType;
    }

    if (fi == null)
        throw new ArgumentOutOfRangeException("propName", string.Format("Field {0} was not found in Type {1}", propName, obj.GetType().FullName));

    return (T)fi.GetValue(obj);
}

作為參考,這些都是不好的:

return Encoding.UTF8.GetByteCount(str) + 1;
return System.Text.ASCIIEncoding.Default.GetByteCount(str) + 1; //  sizeof(int); // sizeof int to keep the size
return System.Text.ASCIIEncoding.Unicode.GetByteCount(str) + sizeof(int); // sizeof int to keep the size

暫無
暫無

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

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