Элегантный способ использовать (все байты) 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();
}
}
}
использование этого подхода позволит использовать как многоразовый, так и читаемый код.