8

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
Community
  • 1
  • 1
I. J. Kennedy
  • 24,725
  • 16
  • 62
  • 87
  • I don't know C#, but in Java, you'd simply just abandon without closing the BinaryWriter. Doesn't the using{...} construct force closing? Then don't use that construct! – Adrian Pronk Oct 27 '09 at 21:47
  • P.S. But you do need to ensure you flush the BinaryWriter before you abandon it. – Adrian Pronk Oct 27 '09 at 21:48

7 Answers7

7

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.

Ricardo Amores
  • 4,597
  • 1
  • 31
  • 45
  • 1
    I don't understand why you're saying it's better to use GetBuffer and then make a copy using Array.Copy. If I wanted a copy I'd just use ToArray. – I. J. Kennedy Oct 29 '09 at 23:28
  • From MSDN doc This method omits unused bytes in MemoryStream from the array. To get the entire buffer, use the GetBuffer method. http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx – Ricardo Amores Oct 30 '09 at 06:51
  • The above "This Method" refers to the MemoryStream.ToArray() – Ricardo Amores Oct 30 '09 at 06:53
5

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
}    
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
2

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
Chris
  • 27,596
  • 25
  • 124
  • 225
2

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.

I. J. Kennedy
  • 24,725
  • 16
  • 62
  • 87
1

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.

H H
  • 263,252
  • 30
  • 330
  • 514
  • But make sure you call B.flush() after you've finished with it in case it hasn't pushed everything through to M. (That's what would be needed in Java, no idea about C#) – Adrian Pronk Oct 27 '09 at 21:50
  • OK, Adrian & Marc, I forgot to Flush(). – H H Oct 27 '09 at 21:52
0

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);
3Dave
  • 28,657
  • 18
  • 88
  • 151
0

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

Ilya Khaprov
  • 2,546
  • 14
  • 23
  • -1 for posting to a website which doesn't allow viewing it's contents for free, which is pretty much useless –  May 07 '10 at 12:00