将 StreamReader 转换为 byte[]

问题描述 投票:0回答:8

我得到结果

StreamReader
对象。

我想将结果转换为

byte[]

如何将

StreamReader
转换为
byte[]

谢谢

c# stream
8个回答
74
投票

只需将您读取的所有内容放入

MemoryStream
并最终获得字节数组。如前所述,您应该从底层流中读取以获取原始字节。

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

或者如果您不想管理缓冲区:

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

47
投票

StreamReader 用于文本,而不是纯字节。不要使用 StreamReader,而是直接从底层流中read


3
投票

您还可以使用复制到:

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

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

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

1
投票

正如 Matti Virkkunen 指出的,您不一定需要 MemoryStream。当流不太长时,可以直接写入数组。分配的内存较少是优点。

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

0
投票

几年过去了,我认为这个实现更好更简单

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

-2
投票

您可以使用此代码:不应该使用此代码:

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

请参阅此答案的评论以了解原因。我会留下答案,以便人们知道这种方法的问题,因为我到目前为止还没有。


-5
投票

对于每个人都说要获取字节,将其复制到

MemoryStream
等 - 如果预计内容不会大于计算机内存应该合理地允许,为什么不只使用
StreamReader
的内置在
ReadLine()
还是
ReadToEnd()
?我发现这些甚至都没有被提及,而他们却为你做了一切。

我有一个用例,我只想存储用户在同步/初始化过程中选择的

FileDialogResult
中的 SQLite 文件的路径。我的程序稍后在正常应用程序进程运行时需要使用此路径。也许不是捕获/重用信息的理想方式,但它与写入/读取 .ini 文件没有太大区别 - 我只是不想为一个值设置一个。所以我只是从一个平面的单行文本文件中读取它。这就是我所做的:

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;

如果出于某种原因您确实需要

byte[]
而不是
string
,使用我的示例,您始终可以这样做:

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;

(返回

toBytes
而不是
path
。)

如果您不想要

ASCII
,您可以轻松地将其替换为
UTF8
Unicode

© www.soinside.com 2019 - 2024. All rights reserved.