发布日期:2018-03-26
从流创建字节数组+ 查看更多
从流创建字节数组
+ 查看更多
发布日期:2018-03-07 14:05
分类:C#
浏览次数:84
从输入流创建字节数组的首选方法是什么?
这是我目前用.NET 3.5做的解决方案。
Stream s; byte[] b; using (BinaryReader br = new BinaryReader(s)) { b = br.ReadBytes(s.Length); }
有没有更好的办法,去读写流?
回答
这真的取决于你是否可以信任 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 返回)的大小相同,那么你可以只是返回缓冲区。尽管上面的代码并没有很好的优化,但至少是正确的。它不负责关闭流 - 调用者会做这件事。
有关更多信息,请参阅这篇文章(和一个替代实现)。
http://www.yoda.arachsys.com/csharp/readbinary.html
http://www.yoda.arachsys.com/csharp/readbinary.html