How to get a MemoryStream from a Stream in .NET?

136,647

Solution 1

If you're modifying your class to accept a Stream instead of a filename, don't bother converting to a MemoryStream. Let the underlying Stream handle the operations:

public class MyClass
{ 
    Stream _s;

    public MyClass(Stream s) { _s = s; }
}

But if you really need a MemoryStream for internal operations, you'll have to copy the data out of the source Stream into the MemoryStream:

public MyClass(Stream stream)
{
    _ms = new MemoryStream();
    CopyStream(stream, _ms);
}

// Merged From linked CopyStream below and Jon Skeet's ReadFully example
public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[16*1024];
    int read;
    while((read = input.Read (buffer, 0, buffer.Length)) > 0)
    {
        output.Write (buffer, 0, read);
    }
}

Solution 2

In .NET 4, you can use Stream.CopyTo to copy a stream, instead of the home-brew methods listed in the other answers.

MemoryStream _ms;

public MyClass(Stream sourceStream)

    _ms = new MemoryStream();
    sourceStream.CopyTo(_ms);
}

Solution 3

Use this:

var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);

This will convert Stream to MemoryStream.

Solution 4

You can simply do:

var ms = new MemoryStream(File.ReadAllBytes(filePath));

Stream position is 0 and ready to use.

Solution 5

I use this combination of extension methods:

    public static Stream Copy(this Stream source)
    {
        if (source == null)
            return null;

        long originalPosition = -1;

        if (source.CanSeek)
            originalPosition = source.Position;

        MemoryStream ms = new MemoryStream();

        try
        {
            Copy(source, ms);

            if (originalPosition > -1)
                ms.Seek(originalPosition, SeekOrigin.Begin);
            else
                ms.Seek(0, SeekOrigin.Begin);

            return ms;
        }
        catch
        {
            ms.Dispose();
            throw;
        }
    }

    public static void Copy(this Stream source, Stream target)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (target == null)
            throw new ArgumentNullException("target");

        long originalSourcePosition = -1;
        int count = 0;
        byte[] buffer = new byte[0x1000];

        if (source.CanSeek)
        {
            originalSourcePosition = source.Position;
            source.Seek(0, SeekOrigin.Begin);
        }

        while ((count = source.Read(buffer, 0, buffer.Length)) > 0)
            target.Write(buffer, 0, count);

        if (originalSourcePosition > -1)
        {
            source.Seek(originalSourcePosition, SeekOrigin.Begin);
        }
    }
Share:
136,647

Related videos on Youtube

fearofawhackplanet
Author by

fearofawhackplanet

Updated on November 03, 2020

Comments

  • fearofawhackplanet
    fearofawhackplanet over 3 years

    I have the following constructor method which opens a MemoryStream from a file path:

    MemoryStream _ms;
    
    public MyClass(string filePath)
    {
        byte[] docBytes = File.ReadAllBytes(filePath);
        _ms = new MemoryStream();
        _ms.Write(docBytes, 0, docBytes.Length);
    }
    

    I need to change this to accept a Stream instead of a file path. Whats the easiest/most efficient way to get a MemoryStream from the Stream object?

    • Justin Niessner
      Justin Niessner almost 14 years
      Once you have the Stream, why bother converting it to a MemoryStream? Can't you just work with the Stream directly?
    • fearofawhackplanet
      fearofawhackplanet almost 14 years
      I need a MemoryStream due to other dependencies.
    • Chris Rae
      Chris Rae almost 6 years
      There are also instances where poor performance working with Streams causes a MemoryStream to be more efficient. Like my question here: stackoverflow.com/questions/50399481/…
  • fearofawhackplanet
    fearofawhackplanet almost 14 years
    I'm presuming that's > 0 at the end of the while line?
  • Justin Niessner
    Justin Niessner almost 14 years
    @fearofawhackplanet - Correct. I got a little delete happy. Fixed.
  • Stephane Delcroix
    Stephane Delcroix almost 11 years
    looks like one closing parenthesis is missing. should be while((read = input.Read(buffer,0,buffer.Length)) > 0)
  • L Co
    L Co over 5 years
    Might want to add output.Position = 0; as the very last line otherwise you'll need to remember to reset it later.
  • David Thielen
    David Thielen about 5 years
    Make sure you first set sourceStream.Position = 0;
  • ScubaSteve
    ScubaSteve about 5 years
    You will need to set _ms.Position = 0; prior to using it as well.
  • Maicon Heck
    Maicon Heck over 4 years
    This is the cleanest and most elegant solution.
  • Cesar
    Cesar over 3 years
    This doesn't answer the question at all!