Problem
What’s the best way to make a byte array out of an input stream?
Here is my current.NET 3.5 solution.
Stream s;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
Is reading and writing parts of the stream still a superior idea?
Asked by Bob
Solution #1
It all boils down to whether or not you can put your faith in s.Length. You just don’t know how much data will be there in various streams. In such circumstances, and before to.NET 4, I’d use the following code:
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
I’d use Stream with.NET 4 and up. Create the MemoryStream, then call stream, which is basically the same as the loop in my code. Return ms.ToArray after CopyTo(ms) (). The task has been completed.
Perhaps I should explain why my response is longer than the others. Stream. Read isn’t a promise that it’ll read all you’ve requested. If you’re reading from a network stream, for example, it might just read one packet before returning, even if additional data is coming soon. BinaryReader. Read will continue until the end of the stream or the size you provide, but you must know the size to begin with.
Until it runs out of data, the aforementioned procedure will keep reading (and copying into a MemoryStream). The MemoryStream is then asked to return a copy of the data in an array. You can design the MemoryStream to be that size to begin with if you know the size to begin with – or think you know the size but aren’t sure. Similarly, if the length of the stream is the same as the buffer (returned by MemoryStream), you can insert a check at the end. If you use GetBuffer), you may just return the buffer. So, while the above code isn’t completely optimized, it will at the very least work. It takes no responsibility for shutting the stream; the caller is responsible for that.
For further information, see this article (and an alternative implementation).
Answered by Jon Skeet
Solution #2
While Jon’s response is accurate, he is rewriting existing code in CopyTo. As a result, Sandip’s solution is used by Net 4, but it is for an older version of. Jon’s response is used by Net. Sandip’s code might benefit from the inclusion of “using,” as exceptions in CopyTo are common in many cases, leaving the MemoryStream undisposed.
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
Answered by Nathan Phillips
Solution #3
I just wanted to remind out that you already have memorystream if you have a MemoryStream. That’s where ToArray() comes in.
Also, if you’re dealing with streams of unknown or varied subtypes and you have access to a MemoryStream, you can utilize that method for such circumstances while sticking to the approved solution for the rest, as seen below:
public static byte[] StreamToByteArray(Stream stream)
{
if (stream is MemoryStream)
{
return ((MemoryStream)stream).ToArray();
}
else
{
// Jon Skeet's accepted answer
return ReadFully(stream);
}
}
Answered by Fernando Neira
Solution #4
MemoryStream ms = new MemoryStream();
file.PostedFile.InputStream.CopyTo(ms);
var byts = ms.ToArray();
ms.Dispose();
Answered by Sandip Patel
Solution #5
Just my two cents… I frequently use the approach of organizing the methods in this manner as a custom assist.
public static class StreamHelpers
{
public static byte[] ReadFully(this Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
}
Include namespace in the config file and use it everywhere you want.
Answered by Mr. Pumpkin
Post is based on https://stackoverflow.com/questions/221925/creating-a-byte-array-from-a-stream