Wenn ein Stream die Eigenschaft Length unterstützt, kann ein Byte-Array direkt erstellt werden. Der Vorteil ist, dass MemoryStream.ToArray
erstellt das Array zweimal. Außerdem befinden sich wahrscheinlich einige ungenutzte zusätzliche Bytes im Puffer. Bei dieser Lösung wird genau das benötigte Array zugewiesen. Wenn der Stream die Eigenschaft Length nicht unterstützt, wird NotSupportedException
Ausnahme.
Es ist auch zu beachten, dass Arrays nicht größer als int.MaxValue sein können.
public static async Task<byte[]> ToArrayAsync(this Stream stream)
{
var array = new byte[stream.Length];
await stream.ReadAsync(array, 0, (int)stream.Length);
return array;
}
Vollständiger Code, der zwischen beiden Versionen umschaltet, je nachdem, ob der Stream das Suchen unterstützt oder nicht.
/// <summary>
/// Converts stream to byte array.
/// </summary>
/// <param name="stream">Stream</param>
/// <returns>Binary data from stream in an array</returns>
public static async Task<byte[]> ToArrayAsync(this Stream stream)
{
if (!stream.CanRead)
{
throw new AccessViolationException("Stream cannot be read");
}
if (stream.CanSeek)
{
return await ToArrayAsyncDirect(stream);
}
else
{
return await ToArrayAsyncGeneral(stream);
}
}
private static async Task<byte[]> ToArrayAsyncGeneral(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
private static async Task<byte[]> ToArrayAsyncDirect(Stream stream)
{
var array = new byte[stream.Length];
await stream.ReadAsync(array, 0, (int)stream.Length);
return array;
}