首页 文章

从流创建字节数组

提问于
浏览
768

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

这是我目前使用.NET 3.5的解决方案 .

Stream s;
byte[] b;

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

读取和写入流的块是否仍然是一个更好的主意?

14 回答

  • -3

    如果有人喜欢它,这里只有一个.NET 4解决方案形成一个扩展方法,而不需要在MemoryStream上进行不必要的Dispose调用 . 这是一个毫无希望的微不足道的优化,但值得注意的是,未能释放MemoryStream并不是真正的失败 .

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

    虽然Jon的回答是正确的,但他正在重写CopyTo中已存在的代码 . 因此.Net 4使用Sandip的解决方案,但对于以前版本的.Net,请使用Jon的答案 . Sandip的代码将通过使用“使用”来改进,因为在很多情况下,CopyTo中的异常很可能会使MemoryStream不被处理掉 .

    public static byte[] ReadFully(Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
    
  • 9
    public static byte[] ToByteArray(Stream stream)
        {
            if (stream is MemoryStream)
            {
                return ((MemoryStream)stream).ToArray();
            }
            else
            {
                byte[] buffer = new byte[16 * 1024];
                using (MemoryStream ms = new MemoryStream())
                {
                    int read;
                    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, read);
                    }
                    return ms.ToArray();
                }
            }            
        }
    
  • 1127

    你甚至可以通过扩展来让它变得更加漂亮:

    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()
    
  • 0

    你可以简单地使用MemoryStream类的ToArray()方法,

    MemoryStream ms = (MemoryStream)dataInStream;
    byte[] imageBytes = ms.ToArray();
    
  • 1

    我能够让它在一条线上工作:

    byte [] byteArr= ((MemoryStream)localStream).ToArray();
    

    正如johnnyRose所阐明的,上面的代码只适用于MemoryStream

  • -1

    这真的取决于你是否可以信任 s.Length . 对于许多流,你只需要使用这样的代码:

    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没有't guarantee that it will read everything it'的要求 . 如果你的 Value 然后返回,即使很快就会有更多的数据 . BinaryReader.Read将继续运行直到流的末尾或您指定的大小,但您仍然必须知道要开始的大小 .

    上述方法将继续读取(并复制到MemoryStream中),直到数据耗尽为止 . 然后它要求MemoryStream返回数组中的数据副本 . 如果您知道要开始的大小 - 或者认为您知道大小,而不确定 - 您可以将MemoryStream构造为该大小 . 同样,您可以在结尾处进行检查,如果流的长度与缓冲区的大小相同(由MemoryStream.GetBuffer返回),则可以返回缓冲区 . 所以上面的代码不承担任何关闭流的责任 - 调用者应该这样做 .

    有关详细信息,请参阅this article(以及替代实现) .

  • 611

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

    只是我的几分钱...我经常使用的做法是组织像这样的方法作为自定义助手

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

    将命名空间添加到配置文件并在任何地方使用它

  • 58

    我得到了鲍勃(即提问者)代码的编译时错误 . Stream.Length是一个long而BinaryReader.ReadBytes是一个整数参数 . 在我的情况下,我不希望处理大到足以要求长精度的Streams,所以我使用以下内容:

    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);
    }
    
  • 7

    上面的那个是好的...但是当您通过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;
            }'
    
  • 91

    创建一个帮助程序类,并在您希望使用它的任何地方引用它 .

    public static class StreamHelpers
    {
        public static byte[] ReadFully(this Stream input)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                input.CopyTo(ms);
                return ms.ToArray();
            }
        }
    }
    
  • 2
    MemoryStream ms = new MemoryStream();
    file.PostedFile.InputStream.CopyTo(ms);
    var byts = ms.ToArray();
    ms.Dispose();
    
  • 4

    您可以使用此扩展方法 .

    public static class StreamExtensions
    {
        public static byte[] ToByteArray(this Stream stream)
        {
            var bytes = new List<byte>();
    
            int b;
            while ((b = stream.ReadByte()) != -1)
                bytes.Add((byte)b);
    
            return bytes.ToArray();
        }
    }
    

相关问题