Daniel A.A. Pelsmaeker
Daniel A.A. Pelsmaeker

Reputation: 50366

Copy data from MemoryStream directly to BinaryWriter.BaseStream?

I have a bunch of data in a MemoryStream and I want to write all of it to a BinaryWriter.

Lucky for me all streams now have a Stream.CopyTo(Stream) method, and I can get the target stream from the BinaryWriter.BaseStream property.

public void WriteTo(BinaryWriter writer)
{
    this.memoryStream.CopyTo(writer.BaseStream);
}

Can I safely bypass the writer like this and copy it directly to the base stream, or will this mess up the writer's buffer, position, or something else? Or, how would you propose copying a Stream to a BinaryWriter?

Upvotes: 3

Views: 3506

Answers (2)

Jim Mischel
Jim Mischel

Reputation: 134125

What you propose is safe, provided:

  1. That you're using this in a single-threaded context. Either there are no other threads, or you have an exclusive lock on the writer at the time you call this. ... AND
  2. You call Flush on the writer before writing directly to the BaseStream. The writer could have some data buffered that it hasn't yet written to the stream.

So your modified code is:

public void WriteTo(BinaryWriter writer)
{
    writer.Flush();
    this.memoryStream.CopyTo(writer.BaseStream);
}

Upvotes: 2

MeTitus
MeTitus

Reputation: 3428

If you don't want to mess with the data you have in the initial stream would not something like this work:

        var myStreamInitially = new MemoryStream();
        var myStreamClone = new MemoryStream();

        myStreamInitially.CopyTo(myStreamClone);

        var binaryWriteb = new BinaryWriter(myStreamClone);

If you're using .NET 4+ the CopyTo method is very handy.

UPDATE

Isn't this then safer than changing the binaryStream underlying baseStream:

    void WriteToStreamInUnknownStatus(BinaryWriter binaryWriter)
    {
        var myStream = new MemoryStream();

        try
        {
            binaryWriter.Write(myStream.ToArray());
        }
        catch
        { }
    }

UPDATE 2

If you try this you get an exception: "memory stream is not explandable"

   static void Main(string[] args)
    {
        var binaryWrite = new BinaryWriter(new MemoryStream(new byte[] {1, 2, 3, 4}));

        binaryWrite.Seek(3, SeekOrigin.Begin);

        var position = binaryWrite.BaseStream.Position;

        new MemoryStream(new byte[] {1, 2, 3, 4}).CopyTo(binaryWrite.BaseStream);

        position = binaryWrite.BaseStream.Position;
    }

So in top of having to be sure that the property is thread safe you also need to know the type of the inner stream. To risk IMO.

Upvotes: 2

Related Questions