一个 MemoryStream 的 byte[] 缓冲区是否可以具有可变大小?

4

我正在使用MemoryStream将对象序列化为byte[]

byte[] serialized = new byte[1000];
using (MemoryStream stream = new MemoryStream(serialized))
    using (TextWriter textWriter = new StreamWriter(stream))
        serializer.Serialize(textWriter, stuffToSerialize);

有没有办法让'serialized'根据stuffToSerialize的大小自动增长?

2个回答

9

不带参数的构造函数new MemoryStream()使用其中之一。

然后将其序列化,当您需要byte[]时调用ToArray(),它会创建一个实际使用了缓冲区长度的副本(内部缓冲区通常在任何时候都有一些增长空间,这通常是不可取的,ToArray()提供了您真正关心的内容)。

在以下代码的末尾,它将产生与您的代码相同的效果,只要您能够预测正确的大小:

byte[] serialized;
using (MemoryStream stream = new MemoryStream())
{
  using (TextWriter textWriter = new StreamWriter(stream))
  {
    serializer.Serialize(textWriter, stuffToSerialize);
  }
  // Note: you can even call stream.Close here is you are paranoid enough
  // - ToArray/GetBuffer work on disposed MemoryStream objects.
  serialized = stream.ToArray();
}

我不是将它用作另一个变量的缓冲区 - 我正在其中存储序列化对象。 - ispiro
谢谢。我正在尝试执行textWriter.ToArray()操作。 - ispiro
1
+1。请注意,示例缺少必要的Flush调用,或者更好的做法是将调用ToArray移动到内部using之外。正在更新代码... - Alexei Levenkov
非常正确@AlexeiLevenkov,在复制不直接类似的内容时疏忽了。 - Jon Hanna
这段代码无法编译,new MemoryStream(serialized) 应该改为 new MemoryStream()。你不能传递一个未初始化的变量。 - nicodemus13
@nicodemus13 完全正确,这只是因为复制粘贴问题时被遗留下来的,然后生成了答案的变体。 - Jon Hanna

4
如果您使用接受现有byte[]缓冲区的构造函数,则不能,因为一旦分配了数组,它的大小就是固定的。
默认构造函数以及任何不接受byte[]参数的其他构造函数将根据需要用更大的缓冲区替换现有缓冲区。请注意,如果在调用GetBuffer()后追加流,则支持流的实际byte[]可能会被替换。此外,请注意,在调用GetBuffer()时,流数据可能不从返回的数组的索引0开始!
要获取内容,请使用ToArray()将其作为字节数组获取,或使用WriteTo(Stream)MemoryStream的内容倒入另一个流中。

但是我该如何从“textWriter”中获取字节呢? - ispiro
@ispiro ToArray 方法可以获取一个字节数组,或者使用 WriteTo 方法将内容倾倒到另一个流中。 - Jeffrey Hantin
谢谢。我试着执行 textWriter.ToArray() - ispiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接