2011-04-24 70 views
15

假设我抄一个字节的缓冲区为使用该重用内存流

memoryStream.Read(data, 0, data.Length); 

内存流有什么办法,我清空流和重用它来读取额外的数据?

我想,以避免产生很多的MemoryStream对象和喜欢使用一个实例,用法

回答

16

之间重置它可以设置Position为0,这将影响重置流。

但是,正如this答案所示,重复使用内存流不可能为您带来任何性能优势。创建更多内存流更便宜。

另一个选项是使用固定的byte[]作为重复使用的缓冲区。

+1

没错 - 但如果流已经包含了100个字节,我写99个字节,然后当我来到阅读本流,我会读的内容太多:) – 2011-04-24 08:27:44

+1

@CycleMachine - 有一个原因为什么重置/清除内存流不内置。请参阅我已添加的链接答案。 – Oded 2011-04-24 08:33:06

+3

如果你分配一个大缓冲区,重用缓冲区vs每次重新分配会更高效。您可以使用SetLength(0)(请参阅下面的答案)来设置位置,而不是设置位置,这将保持缓冲区分配并重置内部计数器,长度和位置,这比重新分配大型缓冲区更经济。 – 2011-04-24 09:31:08

-1

memoryStream.Seek(0,SeekOrigin.Begin);

19

通过设置位置为0,长度为0

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,你不清除现有的缓冲区可以重复使用的MemoryStream,它只复位内部计数器。因此,现有的缓冲区分配保持不变,但所有使用了多少缓冲区的记录都已重置,以便您可以重新使用它。

更新:我只是简单介绍了SetLength的代码实现,如果将长度设置为0,Position将自动重置为0,因此您甚至不需要显式设置Position属性足以重置长度。

0

如果使用memoryStream.getBuffer()和偏移/长度(使用memoryStream.PositionmemoryStream.Length用于检测边界)用于直接访问byte[]数据这将是更好,Reader/Writer/BinaryFormatter类,或接受Stream,用于读取其它类/写原语/复杂类型放入缓冲区(这就是MemoryStream的作用),你可以在没有无用的复制操作的情况下管理,因为MemoryStream已经基于字节数组。

我用这种方式与异步发送/接收套接字操作接受byte[],但要注意 - 如果你写的东西到缓冲区超越其目前Length,并希望加强与SetLength()长度与Reader类读 - 你会得到非常不方便行为(在我看来) - 如果长度增加,此方法将废除旧长度和新长度之间的每个字节。

我通过修改源代码的MemoryStream(在SetLength()一个Array.Clear电话,以及一些补充而不内部类.NET的管理),并在我的项目中使用它解决了这个问题。

至于重用的MemoryStream,我同意克里斯·泰勒的回答(SetLength(0)