Есть ли простой способ или способ преобразования Stream в byte[] в С#?
Как преобразовать поток в байт [] в С#?
Ответ 1
Вызов следующей функции, например
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; 
            }
        }
    }
Ответ 2
Самое короткое решение, которое я знаю:
using(var memoryStream = new MemoryStream())
{
  sourceStream.CopyTo(memoryStream);
  return memoryStream.ToArray();
}
Ответ 3
В .NET Framework 4 и более поздних версиях класс Stream имеет встроенный метод CopyTo, который вы можете использовать.
Для более ранних версий рамки удобная вспомогательная функция:
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
  Изменить: Первоначально я предложил использовать ответ Джейсона для Stream, который поддерживает свойство Length. Но у него был недостаток, поскольку он предположил, что Stream вернет все его содержимое в один Read, что не обязательно верно (не для Socket, например.) Я не знаю, есть ли пример реализации Stream в BCL, который поддерживает Length, но может возвращать данные в более короткие куски, чем вы запрашиваете, но поскольку любой может наследовать Stream, это может быть легко.
В большинстве случаев проще использовать вышеупомянутое общее решение, но предположим, что вы хотели бы читать непосредственно в массив bigEnough:
byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
    offset += r;
То есть, повторно вызывайте Read и перемещайте позицию, в которой вы будете хранить данные.
Ответ 4
    byte[] buf;  // byte array
    Stream stream=Page.Request.InputStream;  //initialise new stream
    buf = new byte[stream.Length];  //declare arraysize
    stream.Read(buf, 0, buf.Length); // read from stream to byte array
Ответ 5
Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);
Ответ 6
Я использую этот класс расширения:
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()
Отлично работает для всех моих потоков и сохраняет много кода! Конечно, вы можете изменить этот метод, чтобы использовать некоторые из других подходов здесь для повышения производительности, если это необходимо, но мне нравится держать его простым.
Ответ 7
Хорошо, может быть, я что-то пропустил, но так я это делаю:
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;
}
Ответ 8
Быстрая и грязная техника:
    static byte[] StreamToByteArray(Stream inputStream)
    {
        if (!inputStream.CanRead)
        {
            throw new ArgumentException(); 
        }
        // This is optional
        if (inputStream.CanSeek)
        {
            inputStream.Seek(0, SeekOrigin.Begin);
        }
        byte[] output = new byte[inputStream.Length];
        int bytesRead = inputStream.Read(output, 0, output.Length);
        Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length");
        return output;
    }
Тест:
    static void Main(string[] args)
    {
        byte[] data;
        string path = @"C:\Windows\System32\notepad.exe";
        using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
        {
            data = StreamToByteArray(fs);
        }
        Debug.Assert(data.Length > 0);
        Debug.Assert(new FileInfo(path).Length == data.Length); 
    }
Я бы спросил, почему вы хотите прочитать поток в байт [], если вы хотите скопировать содержимое потока, могу ли я предложить использовать MemoryStream и записать поток ввода в поток памяти.
Ответ 9
если вы отправляете файл с мобильного устройства или другого
    byte[] fileData = null;
    using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
    {
        fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
    }
Ответ 10
Stream s;
int len = (int)s.Length;
byte[] b = new byte[len];
int pos = 0;
while((r = s.Read(b, pos, len - pos)) > 0) {
    pos += r;
}
Требуется несколько более сложное решение: s.Length превышает Int32.MaxValue. Но если вам нужно прочитать поток, большой в памяти, вам может понадобиться подумать о другом подходе к вашей проблеме.
Изменить: если ваш поток не поддерживает свойство Length, измените его с помощью метода обхода  .
public static class StreamExtensions {
    // Credit to Earwicker
    public static void CopyStream(this 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);
        }
    }
}
[...]
Stream s;
MemoryStream ms = new MemoryStream();
s.CopyStream(ms);
byte[] b = ms.GetBuffer();
Ответ 11
Вы также можете попробовать просто прочитать по частям за раз и расширить массив байтов:
public byte[] StreamToByteArray(string fileName)
{
    byte[] total_stream = new byte[0];
    using (Stream input = File.Open(fileName, FileMode.Open, FileAccess.Read))
    {
        byte[] stream_array = new byte[0];
        // Setup whatever read size you want (small here for testing)
        byte[] buffer = new byte[32];// * 1024];
        int read = 0;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            stream_array = new byte[total_stream.Length + read];
            total_stream.CopyTo(stream_array, 0);
            Array.Copy(buffer, 0, stream_array, total_stream.Length, read);
            total_stream = stream_array;
        }
    }
    return total_stream;
}
Ответ 12
"BigEnough" массив немного растянут. Разумеется, буфер должен быть "большим", но правильный дизайн приложения должен включать транзакции и разделители. В этой конфигурации каждая транзакция будет иметь заданную длину, поэтому ваш массив будет ожидать определенное количество байтов и вставить его в буфер с правильным размером. Разделители гарантируют целостность транзакции и будут поставляться в рамках каждой транзакции. Чтобы сделать ваше приложение еще лучше, вы можете использовать 2 канала (2 гнезда). Можно было бы связывать транзакции с фиксированной длиной управления, которые будут включать информацию о размере и порядковом номере транзакции данных, которая будет передана с использованием канала данных. Приемник подтвердил создание буфера, и только тогда данные будут отправлены. Если у вас нет контроля над отправителем потока, вам нужен многомерный массив в качестве буфера. Компонентные массивы будут достаточно малы, чтобы быть управляемыми и достаточно большими, чтобы быть практичными на основе вашей оценки ожидаемых данных. Логика процесса будет искать известные начальные разделители и затем заканчивать разделитель в последующих массивах элементов. После обнаружения конечного разделителя будет создан новый буфер для хранения релевантных данных между разделителями и начальным буфером, чтобы можно было удалить данные.
Что касается кода для преобразования потока в массив байтов, то ниже.
Stream s = yourStream;
int streamEnd = Convert.ToInt32(s.Length);
byte[] buffer = new byte[streamEnd];
s.Read(buffer, 0, streamEnd);
