Frage

    

Diese Frage bereits eine Antwort hier:

    
            
  •              Erstellen eines Byte-Array aus einem Strom                                      16 Antworten                          
  •     
    

Gibt es eine einfache Art und Weise oder Methode eine Stream in eine byte[] in C # zu konvertieren?

War es hilfreich?

Lösung

Anruf nächste Funktion wie

byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);

Funktion:

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

Andere Tipps

Die kürzeste Lösung weiß ich:

using(var memoryStream = new MemoryStream())
{
  sourceStream.CopyTo(memoryStream);
  return memoryStream.ToArray();
}

In .NET Framework 4 und später die Stream Klasse verfügt über eine integrierte in CopyTo Methode, die Sie verwenden können.

Für frühere Versionen des Frameworks, die handliche Hilfsfunktion zu haben, ist:

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

Dann wird eine der oben genannten Methoden verwenden, um eine MemoryStream und rufen GetBuffer auf sie zu kopieren:

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

Edit: ursprünglich vorgeschlagen, dass ich Jasons Antwort für eine Stream verwenden, die die Length Eigenschaft unterstützt. Aber es hatte einen Fehler, weil davon ausgegangen, dass der Stream würde alle seine Inhalte in einer einzigen Read zurückkehren, die nicht unbedingt wahr ist (nicht für ein Socket, zum Beispiel.) Ich weiß nicht, ob es ein Beispiel für eine Stream Implementierung in der BCL, die Unterstützung Length tut aber möglicherweise die Daten in kürzeren Stücken zurückgeben, als Sie verlangen, aber wie jeder Stream könnte dies der Fall erben kann leicht sein.

Es ist wahrscheinlich einfacher für die meisten Fälle die obige allgemeine Lösung zu verwenden, aber Angenommen, Sie wollten direkt in ein Array lesen, die bigEnough ist:

byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
    offset += r;

Das heißt, rufen immer wieder Read und die Position bewegen Sie die Daten werden gespeichert werden.

    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

Ich benutze diese Erweiterung Klasse:

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

Kopieren Sie einfach die Klasse zu Ihrer Lösung und man kann es auf jeden Strom verwendet werden:

byte[] bytes = myStream.ReadAllBytes()

Funktioniert hervorragend für alle meine Bäche und spart eine Menge Code! Natürlich können Sie diese Methode ändern hier einige der anderen Ansätze zu verwenden, die Leistung zu verbessern, wenn nötig, aber Ich mag es einfach zu halten.

Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);

Ok, vielleicht bin ich hier etwas fehlt, aber das ist die Art, wie ich es tun:

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

Wenn Sie Beiträge verfassen eine Datei von Mobilgerät oder andere

    byte[] fileData = null;
    using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
    {
        fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
    }

Schnelle und schmutzige Technik:

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

Test:

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

Ich würde fragen, warum Sie einen Stream in ein byte [] lesen tun möchten, wenn Sie den Inhalt eines Streams kopieren zu wollen, kann ich mit Memory vorschlagen und Ihre Eingangsstrom in einen Speicher-Stream zu schreiben.

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

Eine etwas kompliziertere Lösung ist necesary ist s.Length Int32.MaxValue übersteigt. Aber wenn Sie einen Stream lesen müssen, dass großen in den Speicher, könnte man über einen anderen Ansatz, um Ihr Problem zu denken.

Edit: Wenn Ihr Stream nicht die Length Eigenschaft nicht unterstützt, ändern Earwicker der Abhilfe .

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();

Sie könnten auch versuchen, nur in Teilen zu einem Zeitpunkt, zu lesen und den Byte-Array erweitert zurückgegeben werden:

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

„bigEnough“ Array ist ein wenig strecken. Sicher, muss Puffer „big ebough“ aber richtige Gestaltung einer Anwendung sein sollte Transaktionen und Trennzeichen enthalten. In dieser Konfiguration würde jede Transaktion eine vorgegebene Länge somit Ihr Array würde bestimmte Anzahl von Bytes antizipiert und in der richtigen Größe Puffer ein. Trennzeichen würde die Transaktionsintegrität gewährleisten und würde innerhalb jeder Transaktion geliefert werden. Um besser auf Ihre Anwendung selbst, können Sie 2 Kanäle verwenden (2-Buchsen). Man würde feste Länge Steuernachrichtentransaktionen kommunizieren, die Informationen über die Größe und die Sequenznummer der Datentransaktion umfassen würde unter Verwendung von Datenkanal übertragen werden. Empfänger würde Puffer Schöpfung erkennen und nur dann würden Daten gesendet werden. Wenn Sie keine Kontrolle über Stream Absender haben, als Sie müssen mehrdimensionales Array als Puffer. Component-Arrays wäre klein genug, überschaubar und groß genug zu sein, um praktisch zu sein auf der Grundlage Ihrer Schätzung der erwarteten Daten. Prozesslogik würde bekannte Startbegrenzern suchen und dann in nachfolgenden Elementanordnungen Endbegrenzer. Sobald Begrenzer endet gefunden wird, würde neue Puffer Daten zwischen dem Trennzeichen und die ersten Puffer speichern erstellt werden müssen umstrukturiert werden, Daten zur Verfügung zu ermöglichen.

Soweit ein Codestrom in Byte-Array zu konvertieren ist ein unten.

Stream s = yourStream;
int streamEnd = Convert.ToInt32(s.Length);
byte[] buffer = new byte[streamEnd];
s.Read(buffer, 0, streamEnd);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top