我如何在.NET中“分叉”一个流?

如前所述,当BinaryReader或BinaryWriter关闭时,其底层Stream也会关闭(aargh)。 考虑这种情况:例程R通过MemoryStream,比如M ; 我想给M写一些东西,然后将它传递给另一个例程进行更多处理(不一定是写)。 为方便起见,我想在一个BinaryWriter中包装M来完成我的写作。 写完之后,我已经完成了BinaryWriter而不是M

 void R(MemoryStream M) { using (B = new BinaryWriter(M)) { // write some stuff using B } S(M); // now pass M to another routine for further processing } 

但是,我不能在不关闭M情况下处理BinaryStream。

问:有没有办法做以下任何一种情况?

  • 从MemoryStream中提取底层byte [],
  • 克隆一个流
  • 它关闭后重新打开一个流

你最好使用底层的byte []缓冲区

 byte[] buffer = ms.GetBuffer(); 

然后使用Array.Copy()方法复制字节数据。 您可以随意创建新流。

您可以使用MiscUtil.IO.NonClosingStreamWrapper中的MiscUtil.IO.NonClosingStreamWrapper之类的东西,它包装Stream并简单地忽略Close / Dispose请求。 就是为了这个目的。

 void R(MemoryStream M) { using (B = new BinaryWriter(new NonClosingStreamWrapper(M))) { // write some stuff using B } S(M); // now pass M to another routine for further processing } 

您可以:

  • 调用M.ToArray()将流作为字节数组。
  • 子类BinaryWriter并重写Dispose方法以防止关闭子流

感谢几位建议ToArray的人,我得到了正确答案,即“M.GetBuffer”。 ToArray并不是太糟糕,但它

  • 制作副本
  • 只获得部分缓冲区

GetBuffer只是抓取对底层byte []的引用,这就是我所追求的。

只是在这里添加它,一个非常简单的解决方案就是不要 Dispose()编写器。

 void R(MemoryStream M) { B = new BinaryWriter(M); // write some stuff using B B.Flush(); S(M); // now pass M to another routine for further processing } 

现在你只需要担心将B保持在范围内,它将在R()期间保持。

这可能不是最好的解决方案,但值得注意的是读者和作者不需要自行处理。

一种有点天真的方法是使用

 byte buf[] = MemoryStream.ToArray(); 

将流内容复制到字节数组。 你可以把它变成一个流

 MemoryStream ms = new MemoryStream(buf); 

根据这个 M.Clone(); 应该管用。 但我可能错了……