【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
从输入流创建字节数组的首选方法是什么?
这是我目前使用.NET 3.5的解决方案。
Stream s;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
读取和写入流的块是否仍然是一个更好的主意?
#1楼
您甚至可以通过扩展程序使其变得更加漂亮:
namespace Foo
{
public static class Extensions
{
public static byte[] ToByteArray(this Stream stream)
{
using (stream)
{
using (MemoryStream memStream = new MemoryStream())
{
stream.CopyTo(memStream);
return memStream.ToArray();
}
}
}
}
}
然后将其称为常规方法:
byte[] arr = someStream.ToByteArray()
#2楼
上面的那个是好的...但是当您通过SMTP发送内容时(如果需要),您将遇到数据损坏。 我已经改为其他有助于正确发送字节的东西:'
using System;
using System.IO;
private static byte[] ReadFully(string input)
{
FileStream sourceFile = new FileStream(input, FileMode.Open); //Open streamer
BinaryReader binReader = new BinaryReader(sourceFile);
byte[] output = new byte[sourceFile.Length]; //create byte array of size file
for (long i = 0; i < sourceFile.Length; i++)
output[i] = binReader.ReadByte(); //read until done
sourceFile.Close(); //dispose streamer
binReader.Close(); //dispose reader
return output;
}'
#3楼
只是我的几分钱...我经常使用的做法是将这样的方法组织成一个自定义助手
public static class StreamHelpers
{
public static byte[] ReadFully(this Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
}
将命名空间添加到配置文件并在任何地方使用它
#4楼
这真的取决于你是否可以信任s.Length
。 对于许多流,您只是不知道将有多少数据。 在这种情况下 - 在.NET 4之前 - 我会使用这样的代码:
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
使用.NET 4及更高版本,我将使用Stream.CopyTo
,它基本上等同于我的代码中的循环 - 创建MemoryStream
,调用stream.CopyTo(ms)
然后返回ms.ToArray()
。 任务完成。
我或许应该解释为什么我的回答比其他人长。 Stream.Read
并不保证它会读取它所要求的所有内容。 例如,如果您正在从网络流中读取数据,它可能会读取一个数据包的值,然后返回,即使很快会有更多数据。 BinaryReader.Read
将继续运行直到流的末尾或您指定的大小,但您仍然必须知道要开始的大小。
上面的方法将继续读取(并复制到MemoryStream
),直到它用完数据。 然后它要求MemoryStream
返回数组中的数据副本。 如果您知道要开始的大小 - 或者认为您知道大小,而不确定 - 您可以将MemoryStream
构造为该大小。 同样,您可以在结尾处进行检查,如果流的长度与缓冲区的大小相同(由MemoryStream.GetBuffer
返回),那么您只需返回缓冲区即可。 所以上面的代码并没有得到很好的优化,但至少是正确的。 关闭流不承担任何责任 - 调用者应该这样做。
有关更多信息(以及替代实现),请参阅此文章 。
#5楼
只是想指出,如果你有一个MemoryStream你已经有了memorystream.ToArray()
。
此外,如果您正在处理未知或不同子类型的流并且您可以接收MemoryStream
,则可以针对这些情况继续使用所述方法,并仍然使用其他人接受的答案,如下所示:
public static byte[] StreamToByteArray(Stream stream)
{
if (stream is MemoryStream)
{
return ((MemoryStream)stream).ToArray();
}
else
{
// Jon Skeet's accepted answer
return ReadFully(stream);
}
}
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3144135