重用内存流

时间:2011-04-24 08:22:09

标签: c#

假设我已使用此

将字节缓冲区复制到内存流中
memoryStream.Read(data, 0, data.Length);

有没有办法让我清空流并重复使用它来读取其他数据?

我想避免创建许多MemoryStream对象,而是希望使用一个实例,在用法之间重置它

4 个答案:

答案 0 :(得分:30)

您可以通过将Position设置为0并将Length设置为0来重新​​使用MemoryStream。

MemoryStream ms = new MemoryStream();

// Do some stuff with the stream

// Reset the stream so you can re-use it
ms.Position = 0; // Not actually needed, SetLength(0) will reset the Position anyway
ms.SetLength(0);

// Do some more stuff with the stream

通过将长度设置为0,您不会清除现有缓冲区,它只会重置内部计数器。因此,现有的缓冲区分配保持不变,但是重置所有缓冲区的所有簿记都会被重置,以便您可以重复使用它。

更新:我刚看了一下SetLength的代码实现,如果你将长度设置为0,Position会自动重置为0,所以你甚至不需要显式设置位置属性足以重置长度。

答案 1 :(得分:17)

您可以将Position设置为0,这实际上会重置流。

但是,正如this回答所示,重用内存流不会带来任何性能优势。创建更多内存流会更便宜。

使用固定byte[]作为缓冲区进行重用的另一种选择。

答案 2 :(得分:0)

如果您使用memoryStream.getBuffer()和偏移/长度(使用memoryStream.PositionmemoryStream.Length来检测边界)来直接访问byte[]数据,{{1} } / Reader / Writer类或其他接受BinaryFormatter的类,用于读取/写入原始/复杂类型到缓冲区(这是Stream的用途),您管理没有无用的复制操作,因为MemoryStream已经基于字节数组。

我以这种方式使用异步发送/接收套接字操作接受MemoryStream,但要注意 - 如果你在缓冲区中写入超出其当前byte[]的内容并希望用{{1}增加其长度使用Reader类读取 - 你会得到非常不方便的行为(在我看来) - 如果长度增加,这个方法会使旧长度和新长度之间的每个字节无效。

我通过修改Length的源代码(SetLength()中的一个Array.Clear调用,以及一些没有.NET内部类的管理添加)并在我的项目中使用它来解决这个问题。 / p>

至于重用MemoryStream,我同意Chris Taylor的回答(SetLength()

答案 3 :(得分:-1)

memoryStream.Seek(0,SeekOrigin.Begin);