[c#] Convert StreamReader to byte[]

I am getting the result StreamReader object.

I want to convert the result into byte[].

How can I convert StreamReaderto byte[]?

Thanks

This question is related to c# stream

The answer is


A StreamReader is for text, not plain bytes. Don't use a StreamReader, and instead read directly from the underlying stream.


You can use this code: You shouldn't use this code:

byte[] bytes = streamReader.CurrentEncoding.GetBytes(streamReader.ReadToEnd());

Please see the comment to this answer as to why. I will leave the answer, so people know about the problems with this approach, because I didn't up till now.


For everyone saying to get the bytes, copy it to MemoryStream, etc. - if the content isn't expected to be larger than computer's memory should be reasonably be expected to allow, why not just use StreamReader's built in ReadLine() or ReadToEnd()? I saw these weren't even mentioned, and they do everything for you.

I had a use-case where I just wanted to store the path of a SQLite file from a FileDialogResult that the user picks during the synching/initialization process. My program then later needs to use this path when it is run for normal application processes. Maybe not the ideal way to capture/re-use the information, but it's not much different than writing to/reading from an .ini file - I just didn't want to set one up for one value. So I just read it from a flat, one-line text file. Here's what I did:

string filePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!filePath.EndsWith(@"\")) temppath += @"\"; // ensures we have a slash on the end
filePath = filePath.Replace(@"\\", @"\"); // Visual Studio escapes slashes by putting double-slashes in their results - this ensures we don't have double-slashes
filePath += "SQLite.txt";

string path = String.Empty;
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
path = sr.ReadLine();  // can also use sr.ReadToEnd();
sr.Close();
fs.Close();
fs.Flush();

return path;

If you REALLY need a byte[] instead of a string for some reason, using my example, you can always do:

byte[] toBytes;
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
toBytes = Encoding.ASCII.GetBytes(path);
sr.Close();
fs.Close();
fs.Flush();

return toBytes;

(Returning toBytes instead of path.)

If you don't want ASCII you can easily replace that with UTF8, Unicode, etc.


Just throw everything you read into a MemoryStream and get the byte array in the end. As noted, you should be reading from the underlying stream to get the raw bytes.

var bytes = default(byte[]);
using (var memstream = new MemoryStream())
{
    var buffer = new byte[512];
    var bytesRead = default(int);
    while ((bytesRead = reader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
        memstream.Write(buffer, 0, bytesRead);
    bytes = memstream.ToArray();
}

Or if you don't want to manage the buffers:

var bytes = default(byte[]);
using (var memstream = new MemoryStream())
{
    reader.BaseStream.CopyTo(memstream);
    bytes = memstream.ToArray();
}

You can also use CopyTo:

var ms = new MemoryStream();
yourStreamReader.BaseStream.CopyTo(ms); // blocking call till the end of the stream
ms.GetBuffer().CopyTo(yourArray, ms.Length);

or

var ms = new MemoryStream();
var ct = yourStreamReader.BaseStream.CopyToAsync(ms);
await ct;
ms.GetBuffer().CopyTo(yourArray, ms.Length);