繁体   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