使用System.IO.BinaryWriter编写字符串与char数组的区别

Cra*_*and 4 c# string encoding binaryfiles file

我正在用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());
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么当我只写3个ASCII字符时,字符串重载会写入4个字节.有谁能解释一下?

Eri*_*bal 13

BinaryWriter.Write(string)状态的文档,它将长度为前缀的字符串写入此流.过载Write(char[])没有这样的前缀.

在我看来,额外的数据是长度.

编辑:

只是为了更明确一点,使用Reflector.你会看到它在这里有一段代码作为Write(string)方法的一部分:

this.Write7BitEncodedInt(byteCount);
Run Code Online (Sandbox Code Playgroud)

这是一种使用尽可能少的字节数对整数进行编码的方法.对于短字符串(我们将每天使用少于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);
}
Run Code Online (Sandbox Code Playgroud)

在使用此编码为长度添加前缀后,它会以所需的编码写入字符的字节.

  • +1; 当你看到如何**读取数据时,差异变得更加清晰; 使用BinaryReader.ReadChars你需要告诉它有多少阅读; 使用BinaryReader.ReadString,它使用长度前缀为您执行此操作. (2认同)

jas*_*son 5

来自BinaryWriter.Write(string) 文档:

在BinaryWriter的当前编码中将长度为前缀的字符串写入此流,并根据使用的编码和写入流的特定字符推进流的当前位置.

这种行为可能是因为当使用BinaryReader字符串读取文件时可以识别.(例如,3Foo3Bar6Foobar可以解析为字符串"Foo","Bar"和"Foobar"但FooBarFoobar不能.)实际上,BinaryReader.ReadString使用这些信息来string从二进制文件中读取a .

来自BinaryWriter.Write(char[]) 文档:

将字符数组写入当前流,并根据使用的编码和写入流的特定字符推进流的当前位置.

很难夸大MSDN上文档的全面性和实用性.始终先检查它们.