1088 Stimmen

Erstellen eines Byte-Arrays aus einem Stream

Was ist die bevorzugte Methode zur Erstellung eines Byte-Arrays aus einem Eingabestrom?

Hier ist meine aktuelle Lösung mit .NET 3.5.

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes((int)s.Length);
}

Ist es immer noch eine bessere Idee, Teile des Datenstroms zu lesen und zu schreiben?

5voto

NothinRandom Punkte 215

Die obige Version ist in Ordnung... aber Sie werden Datenfehler feststellen, wenn Sie etwas über SMTP senden (falls Sie das müssen). Ich habe auf etwas anderes umgestellt, das hilft, Byte für Byte korrekt zu senden: '

using System;
using System.IO;

        private static byte[] ReadFully(string input)
        {
            FileStream sourceFile = new FileStream(input, FileMode.Open); //Open streamer
            BinaryReader binReader = new BinaryReader(sourceFile);
            byte[] output = new byte[sourceFile.Length]; //create byte array of size file
            for (long i = 0; i < sourceFile.Length; i++)
                output[i] = binReader.ReadByte(); //read until done
            sourceFile.Close(); //dispose streamer
            binReader.Close(); //dispose reader
            return output;
        }'

4voto

Erstellen Sie eine Hilfsklasse und referenzieren Sie sie überall dort, wo Sie sie verwenden möchten.

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
}

4voto

Wieslaw Olborski Punkte 117

Im Namespace RestSharp.Extensions gibt es die Methode ReadAsBytes. Innerhalb dieser Methode wird MemoryStream verwendet und es gibt den gleichen Code wie in einigen Beispielen auf dieser Seite, aber wenn Sie RestSharp verwenden, ist dies der einfachste Weg.

using RestSharp.Extensions;
var byteArray = inputStream.ReadAsBytes();

4voto

adsamcik Punkte 1195

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;
}

3voto

Fred.S Punkte 64

Dies ist die Funktion, die ich benutze, getestet und gut funktioniert. Bitte beachten Sie, dass 'input' nicht null sein sollte und 'input.position' vor dem Lesen auf '0' zurückgesetzt werden sollte, da sonst die Leseschleife unterbrochen wird und nichts gelesen wird, um in ein Array zu konvertieren.

    public static byte[] StreamToByteArray(Stream input)
    {
        if (input == null)
            return null;
        byte[] buffer = new byte[16 * 1024];
        input.Position = 0;
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            byte[] temp = ms.ToArray();

            return temp;
        }
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X