在c#中是否有简单的方法或方法将流转换为字节[]?


当前回答

我知道的最简单的解决方法是:

using(var memoryStream = new MemoryStream())
{
  sourceStream.CopyTo(memoryStream);
  return memoryStream.ToArray();
}

其他回答

在. net Framework 4及以后版本中,Stream类有一个内置的CopyTo方法可供使用。

对于框架的早期版本,方便的helper函数是:

public static void CopyStream(Stream input, Stream output)
{
    byte[] b = new byte[32768];
    int r;
    while ((r = input.Read(b, 0, b.Length)) > 0)
        output.Write(b, 0, r);
}

然后使用上面的方法之一复制到MemoryStream并调用GetBuffer:

var file = new FileStream("c:\\foo.txt", FileMode.Open);

var mem = new MemoryStream();

// If using .NET 4 or later:
file.CopyTo(mem);

// Otherwise:
CopyStream(file, mem);

// getting the internal buffer (no additional copying)
byte[] buffer = mem.GetBuffer();
long length = mem.Length; // the actual length of the data 
                          // (the array may be longer)

// if you need the array to be exactly as long as the data
byte[] truncated = mem.ToArray(); // makes another copy

编辑:最初我建议使用Jason的答案为支持长度属性的流。但是它有一个缺陷,因为它假设Stream会在一个Read中返回它的所有内容,这并不一定是正确的(例如,对于Socket来说就不是这样)。我不知道在BCL中是否有一个流实现的例子,它支持长度,但可能会以比你请求的更短的块返回数据,但任何人都可以继承流,这很容易是这样的情况。

在大多数情况下,使用上面的通解可能会更简单,但假设你确实想直接读入一个bigEnough数组:

byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
    offset += r;

也就是说,反复调用Read并移动将要存储数据的位置。

我使用这个扩展类:

public static class StreamExtensions
{
    public static byte[] ReadAllBytes(this Stream instream)
    {
        if (instream is MemoryStream)
            return ((MemoryStream) instream).ToArray();

        using (var memoryStream = new MemoryStream())
        {
            instream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
}

只需复制类到您的解决方案,您可以在每个流上使用它:

byte[] bytes = myStream.ReadAllBytes()

工作伟大的所有我的流和节省了大量的代码! 当然,如果需要,您可以修改此方法,使用这里的一些其他方法来提高性能,但我希望保持简单。

像这样调用下一个函数

byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);

功能:

public static byte[] ReadToEnd(System.IO.Stream stream)
{
    long originalPosition = 0;

    if(stream.CanSeek)
    {
         originalPosition = stream.Position;
         stream.Position = 0;
    }

    try
    {
        byte[] readBuffer = new byte[4096];

        int totalBytesRead = 0;
        int bytesRead;

        while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
        {
            totalBytesRead += bytesRead;

            if (totalBytesRead == readBuffer.Length)
            {
                int nextByte = stream.ReadByte();
                if (nextByte != -1)
                {
                    byte[] temp = new byte[readBuffer.Length * 2];
                    Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                    Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                    readBuffer = temp;
                    totalBytesRead++;
                }
            }
        }

        byte[] buffer = readBuffer;
        if (readBuffer.Length != totalBytesRead)
        {
            buffer = new byte[totalBytesRead];
            Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
        }
        return buffer;
    }
    finally
    {
        if(stream.CanSeek)
        {
             stream.Position = originalPosition; 
        }
    }
}
Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);

好吧,也许我在这里遗漏了一些东西,但我是这样做的:

public static Byte[] ToByteArray(this Stream stream) {
    Int32 length = stream.Length > Int32.MaxValue ? Int32.MaxValue : Convert.ToInt32(stream.Length);
    Byte[] buffer = new Byte[length];
    stream.Read(buffer, 0, length);
    return buffer;
}