【发布时间】:2011-08-17 13:21:06
【问题描述】:
我得到了StreamReader对象的结果。
我想将结果转换成byte[]。
如何将StreamReader转换为byte[]?
谢谢
【问题讨论】:
我得到了StreamReader对象的结果。
我想将结果转换成byte[]。
如何将StreamReader转换为byte[]?
谢谢
【问题讨论】:
您可以使用此代码:您不应使用此代码:
byte[] bytes = streamReader.CurrentEncoding.GetBytes(streamReader.ReadToEnd());
请参阅对此答案的评论以了解原因。我会留下答案,所以人们知道这种方法的问题,因为我直到现在才知道。
【讨论】:
StreamReader 用于文本,而不是纯字节。不要使用 StreamReader,而是直接来自底层流的read。
【讨论】:
只需将您读到的所有内容都放入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();
}
【讨论】:
default() 有什么用?我不认为它使事情更具可读性。
MemoryStream 将在我们读取数据时为我们管理大小。
var 关键字(对于大多数局部变量)。我不希望每个人都对此感到满意,但我可以接受。
MemoryStream 的效率可能稍高一些,因为它旨在有效地处理字节数组。例如,您可以使用Write 仅添加数组的一部分(与List<T> 上的AddRange 不同),并且它不通过接口访问字节数组,这可能会稍微降低效率。您也可以直接使用GetBuffer() 获取底层数组,而无需创建它的副本。当然,这仅在您拥有大量数据时才重要。
您也可以使用 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);
【讨论】:
对于每个说要获取字节的人,将其复制到 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 等。
【讨论】:
path,一个字符串变量(因为当你想从文件中读取文本时为什么需要字节?!)。但我还介绍了如何将该字符串转换为字节(如果确实需要字节)。
Encoding.ASCII.GetBytes(...),但快速查看文档显示它提到了 7 位,因此输入很可能会被破坏。类似地,UTF-8 编码对输入进行假设,当输入任意二进制文件时,这些假设也不成立。
Encoding.ASCII.GetBytes(),还有Encoding.UTF8.GetBytes()、Encoding.Unicode.GetBytes() 等。在拼命回答之前使用智能感知。
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()) ;
}
}
【讨论】: