Элегантный способ использовать (все байты) BinaryReader?

есть ли элегантный, чтобы подражать StreamReader.ReadToEnd метод BinaryReader? Возможно, поместить все байты в массив байтов?

Я делаю так:

read1.ReadBytes((int)read1.BaseStream.Length);

...но должен быть способ получше.

4 ответов


просто:

byte[] allData = read1.ReadBytes(int.MaxValue);

на документация говорит, что он будет читать все байты до тех пор, пока конец потока достигается.


обновление

хотя это кажется элегантным, и документация, похоже, указывает, что это будет работать, фактический реализация (проверено в .NET 2, 3.5 и 4) выделяет полноразмерный массив байтов для данных, что, вероятно, вызовет OutOfMemoryException на 32-разрядной системе.

поэтому, я бы сказал, что на самом деле нет элегантного способа.

вместо этого я бы рекомендовал следующий вариант ответа @iano. Этот вариант не зависит от .NET 4:
Создайте метод расширения для BinaryReader (или Stream, код одинаковый для обоих).

public static byte[] ReadAllBytes(this BinaryReader reader)
{
    const int bufferSize = 4096;
    using (var ms = new MemoryStream())
    {
        byte[] buffer = new byte[bufferSize];
        int count;
        while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
            ms.Write(buffer, 0, count);
        return ms.ToArray();
    }

}

нет легко способ сделать это с помощью BinaryReader. Если вы не знаете счет, который вам нужно прочитать заранее, лучше использовать MemoryStream:

public byte[] ReadAllBytes(Stream stream)
{
    using (var ms = new MemoryStream())
    {
        stream.CopyTo(ms);
        return ms.ToArray();
    }
}

чтобы избежать дополнительной копии при вызове ToArray(), вы можете вместо этого вернуть Position и буфера, через GetBuffer().


чтобы скопировать содержимое потока в другой, я решил прочитать" некоторые " байты до конца файла:

private const int READ_BUFFER_SIZE = 1024;
using (BinaryReader reader = new BinaryReader(responseStream))
{
    using (BinaryWriter writer = new BinaryWriter(File.Open(localPath, FileMode.Create)))
    {
        int byteRead = 0;
        do
        {
            byte[] buffer = reader.ReadBytes(READ_BUFFER_SIZE);
            byteRead = buffer.Length;
            writer.Write(buffer);
            byteTransfered += byteRead;
        } while (byteRead == READ_BUFFER_SIZE);                        
    }                
}

другой подход к этой проблеме-использовать методы расширения C#:

public static class StreamHelpers
{
   public static byte[] ReadAllBytes(this BinaryReader reader)
   {
      // Pre .Net version 4.0
      const int bufferSize = 4096;
      using (var ms = new MemoryStream())
      {
        byte[] buffer = new byte[bufferSize];
        int count;
        while ((count = reader.Read(buffer, 0, buffer.Length)) != 0)
            ms.Write(buffer, 0, count);
        return ms.ToArray();
      }

      // .Net 4.0 or Newer
      using (var ms = new MemoryStream())
      {
         stream.CopyTo(ms);
         return ms.ToArray();
      }
   }
}

использование этого подхода позволит использовать как многоразовый, так и читаемый код.