我如何在.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(); 应该管用。 但我可能错了……