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

时间:2009-10-27 21:04:58

标签: c# stream clone memorystream

作为discussed before,当BinaryReader或BinaryWriter关闭时,其底层Stream也会关闭(aargh)。考虑这种情况:例程R传递一个MemoryStream,比如M;我想给M写一些东西,然后将它传递给另一个例程以进行更多处理(不一定要写)。为方便起见,我想将M包装在BinaryWriter中以进行写作。写完之后,我已经完成了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 [],
  • 克隆一个流
  • 关闭后重新打开流

7 个答案:

答案 0 :(得分:7)

您最好使用

获取基础byte []缓冲区
byte[] buffer = ms.GetBuffer();

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

答案 1 :(得分:5)

您可以使用MiscUtilMiscUtil.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
}    

答案 2 :(得分:2)

你可以:

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

答案 3 :(得分:2)

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

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

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

答案 4 :(得分:1)

只是在这里添加它,一个非常简单的解决方案是来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()期间保持。

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

答案 5 :(得分:0)

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

byte buf[] = MemoryStream.ToArray();

将流内容复制到字节数组。您可以使用

将其重新转换为流
MemoryStream ms = new MemoryStream(buf);

答案 6 :(得分:-1)

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