usr021986
usr021986

Reputation: 3511

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

Upvotes: 59

Views: 158014

Answers (7)

Angelo Bernardi
Angelo Bernardi

Reputation: 121

Since a few years have gone by, I think this implementation is better and simpler

using(var ms = new MemoryStream())
{
    await yourStreamReader.BaseStream.CopyToAsync(ms);
    //now you can do whatever you want with ms like returning it as a Base64 string
    return Convert.ToBase64String(ms.ToArray());
}

Upvotes: 0

Manuel
Manuel

Reputation: 167

As Matti Virkkunen pointed out, you don't neccessarily need the MemoryStream. When the stream is not too long you can write into an array directly. Less allocated memory is the advantage.

using (var stream = File.OpenRead("your_file.ext"))
{
    var length = stream.Length;
    if (length <= int.MaxValue)
    {
        var result = new byte[length];
        var bytesRead = stream.Read(result, 0, (int)length);
        if (bytesRead == length) return result;
    }
    //fallback
    using (var memoryStream = new MemoryStream())
    {
        stream.CopyTo(memoryStream);
        return memoryStream.ToArray();
    }
}

Upvotes: 2

Jun Liu
Jun Liu

Reputation: 11

        BlobClient blob = container.GetBlobClient(path);
        //blob.DownloadTo(@"temp\"+ file);
        var response = blob.DownloadContent();
        var stream = response.Value.Content.ToStream();
        using (var sr = new StreamReader(stream))
        {
            using (MemoryStream ms = new MemoryStream())
            {
                sr.BaseStream.CopyTo(ms);
                return Convert.ToBase64String(ms.ToArray()) ;
            }
        }

Upvotes: 1

vapcguy
vapcguy

Reputation: 7537

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.

Upvotes: -6

Mikl X
Mikl X

Reputation: 1249

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);

Upvotes: 3

Jeff Mercado
Jeff Mercado

Reputation: 134801

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();
}

Upvotes: 75

Matti Virkkunen
Matti Virkkunen

Reputation: 65116

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

Upvotes: 47

Related Questions