从输入流创建字节数组的首选方法是什么?

下面是我目前使用。net 3.5的解决方案。

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes((int)s.Length);
}

读写流的块仍然是一个更好的主意吗?


当前回答

如果有人喜欢它,这里有一个。net 4+的解决方案,它是一个扩展方法,没有对MemoryStream进行不必要的Dispose调用。这是一个无可救药的琐碎优化,但值得注意的是,未能Dispose MemoryStream并不是真正的失败。

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        var ms = new MemoryStream();
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

其他回答

我得到了Bob(即提问者)代码的编译时错误。流。Length是一个长而BinaryReader。ReadBytes接受一个整型参数。在我的情况下,我不期望处理足够大的流,需要很长的精度,所以我使用以下:

Stream s;
byte[] b;

if (s.Length > int.MaxValue) {
  throw new Exception("This stream is larger than the conversion algorithm can currently handle.");
}

using (var br = new BinaryReader(s)) {
  b = br.ReadBytes((int)s.Length);
}

将两个投票最多的答案组合成一个扩展方法:

public static byte[] ToByteArray(this Stream stream)
{
    if (stream is MemoryStream)
        return ((MemoryStream)stream).ToArray();
    else
    {
        using MemoryStream ms = new();
        stream.CopyTo(ms);
        return ms.ToArray();
    }            
}

只是想指出,如果你有一个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);
    }
}

虽然Jon的回答是正确的,但他正在重写CopyTo中已经存在的代码。所以对于。net 4使用Sandip的解决方案,但是对于以前版本的。net使用Jon的答案。Sandip的代码将通过使用“using”作为CopyTo中的异常而得到改进,在许多情况下,很可能会留下MemoryStream不被处理。

public static byte[] ReadFully(Stream input)
{
    using (MemoryStream ms = new MemoryStream())
    {
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

在命名空间RestSharp中。扩展有ReadAsBytes方法。在这个方法中使用的是MemoryStream,在本页的一些例子中有相同的代码,但当你使用RestSharp时,这是最简单的方法。

using RestSharp.Extensions;
var byteArray = inputStream.ReadAsBytes();