我正在获取结果StreamReader
对象。
我想把结果转换成byte[]
。
如何将StreamReader
转换为byte[]
?
谢谢
只需将您读取的所有内容放入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();
}
StreamReader用于文本,而不是纯字节。不要使用StreamReader,而是直接从底层流中读取。
你也可以使用CopyTo:
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);
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()) ;
}
}
正如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();
}
}
byte[] bytes = streamReader.CurrentEncoding.GetBytes(streamReader.ReadToEnd());
请参阅对这个答案的评论。我将留下答案,让人们知道这种方法的问题,因为我到现在还没有。
对于每个人都说要获得字节,将其复制到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
等代替。