How to get a MemoryStream from a Stream in .NET?
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);
}
}
Related videos on Youtube
fearofawhackplanet
Updated on November 03, 2020Comments
-
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 aMemoryStream
from theStream
object?-
Justin Niessner almost 14 yearsOnce you have the Stream, why bother converting it to a MemoryStream? Can't you just work with the Stream directly?
-
fearofawhackplanet almost 14 yearsI need a MemoryStream due to other dependencies.
-
Chris Rae almost 6 yearsThere 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 almost 14 yearsI'm presuming that's
> 0
at the end of the while line? -
Justin Niessner almost 14 years@fearofawhackplanet - Correct. I got a little delete happy. Fixed.
-
Stephane Delcroix almost 11 yearslooks like one closing parenthesis is missing. should be
while((read = input.Read(buffer,0,buffer.Length)) > 0)
-
L Co over 5 yearsMight want to add
output.Position = 0;
as the very last line otherwise you'll need to remember to reset it later. -
David Thielen about 5 yearsMake sure you first set sourceStream.Position = 0;
-
ScubaSteve about 5 yearsYou will need to set _ms.Position = 0; prior to using it as well.
-
Maicon Heck over 4 yearsThis is the cleanest and most elegant solution.
-
Cesar over 3 yearsThis doesn't answer the question at all!