从输入流建立字节数组的首选方法是什么? html
这是我目前使用.NET 3.5的解决方案。 数组
Stream s; byte[] b; using (BinaryReader br = new BinaryReader(s)) { b = br.ReadBytes((int)s.Length); }
读取和写入流的块是否仍然是一个更好的主意? 网络
您甚至能够经过扩展程序使其变得更加漂亮: ide
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()
上面的那个是好的...可是当您经过SMTP发送内容时(若是须要),您将遇到数据损坏。 我已经改成其余有助于正确发送字节的东西:' this
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; }'
只是个人几分钱...我常常使用的作法是将这样的方法组织成一个自定义助手 spa
public static class StreamHelpers { public static byte[] ReadFully(this Stream input) { using (MemoryStream ms = new MemoryStream()) { input.CopyTo(ms); return ms.ToArray(); } } }
将命名空间添加到配置文件并在任何地方使用它 code
这真的取决于你是否能够信任s.Length
。 对于许多流,您只是不知道将有多少数据。 在这种状况下 - 在.NET 4以前 - 我会使用这样的代码: htm
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()
。 任务完成。 get
我或许应该解释为何个人回答比其余人长。 Stream.Read
并不保证它会读取它所要求的全部内容。 例如,若是您正在从网络流中读取数据,它可能会读取一个数据包的值,而后返回,即便很快会有更多数据。 BinaryReader.Read
将继续运行直到流的末尾或您指定的大小,但您仍然必须知道要开始的大小。
上面的方法将继续读取(并复制到MemoryStream
),直到它用完数据。 而后它要求MemoryStream
返回数组中的数据副本。 若是您知道要开始的大小 - 或者认为您知道大小,而不肯定 - 您能够将MemoryStream
构造为该大小。 一样,您能够在结尾处进行检查,若是流的长度与缓冲区的大小相同(由MemoryStream.GetBuffer
返回),那么您只需返回缓冲区便可。 因此上面的代码并无获得很好的优化,但至少是正确的。 关闭流不承担任何责任 - 调用者应该这样作。
有关更多信息(以及替代实现),请参阅此文章 。
只是想指出,若是你有一个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); } }