How do I “fork” a Stream in .NET?

你说的曾经没有我的故事 提交于 2019-12-22 04:33:35

问题


As discussed before, when a BinaryReader or BinaryWriter gets closed, its underlying Stream get closed as well (aargh). Consider this situation: a routine R is passed a MemoryStream, say M; I would like to write some stuff to M and then pass it to another routine for more processing (not necessarily writing). For convenience, I'd like to wrap M in a BinaryWriter to do my writing. After writing, I'm done with the BinaryWriter but not with 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
}

But, I can't dispose of the BinaryStream without closing M.

Q: Is there a way to do any of the following?

  • extract the underlying byte[] from a MemoryStream,
  • clone a Stream
  • reopen a Stream after it's been closed

回答1:


You should better get the underlying byte[] buffer using

byte[] buffer = ms.GetBuffer();

And then copy the byte data using the Array.Copy() method. You are free to create a new stream with it.




回答2:


You can use things like the MiscUtil.IO.NonClosingStreamWrapper in MiscUtil, which wraps a Stream and simply ignores Close/Dispose requests. For just this purpose.

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
}    



回答3:


You can:

  • Call M.ToArray() to get the stream as an array of bytes.
  • Subclass BinaryWriter and override the Dispose method to prevent closing of the child stream



回答4:


Thanks to several who suggested ToArray, I was led to right answer, which is `M.GetBuffer'. ToArray is not too bad, but it

  • makes a copy
  • gets only part of the buffer

GetBuffer just grabs a reference to the underlying byte[], which is what I'm after.




回答5:


Just to add it in here, a very simple solution would be not to Dispose() the writer.

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
}

Now you only have to worry about keeping B in scope, which it will be during R().

This may not be the best solution here, but it is worth noting that the Readers and Writers don't need Disposing themselves.




回答6:


A somewhat naive approach is to use

byte buf[] = MemoryStream.ToArray();

To copy the stream contents to a byte array. You can turn it back into a stream with

MemoryStream ms = new MemoryStream(buf);



回答7:


Accoring to this M.Clone(); should work. But i may be wrong...



来源:https://stackoverflow.com/questions/1633672/how-do-i-fork-a-stream-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!