570 Stimmen

Wie kann ich den Inhalt eines Streams in einen anderen kopieren?

Wie lässt sich der Inhalt eines Streams am besten in einen anderen kopieren? Gibt es eine Standardmethode für diese Aufgabe?

742voto

Nick Punkte 13044

Ab .NET 4.5 gibt es die Stream.CopyToAsync Methode

input.CopyToAsync(output);

Dies führt zu einer Task die nach der Fertigstellung fortgesetzt werden können, etwa so:

await input.CopyToAsync(output)

// Code from here on will be run in a continuation.

Beachten Sie, dass je nachdem, wo der Aufruf von CopyToAsync ausgeführt wird, kann der nachfolgende Code auf demselben Thread fortgesetzt werden, der ihn aufgerufen hat, oder auch nicht.

El SynchronizationContext die beim Aufruf von await bestimmt, in welchem Thread die Fortsetzung ausgeführt wird.

Außerdem führt dieser Aufruf (und dies ist ein Implementierungsdetail, das sich noch ändern kann) immer noch Lese- und Schreibvorgänge durch (es wird nur kein Thread verschwendet, der auf den Abschluss der E/A blockiert).

Ab .NET 4.0 gibt es die Funktion Stream.CopyTo Methode

input.CopyTo(output);

Für .NET 3.5 und früher

Das Framework bietet hierfür keine Hilfestellung; Sie müssen den Inhalt manuell kopieren, etwa so:

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write (buffer, 0, read);
    }
}

Hinweis 1: Diese Methode ermöglicht es Ihnen, den Fortschritt zu melden (x bisher gelesene Bytes ...)
Anmerkung 2: Warum eine feste Puffergröße verwenden und nicht input.Length ? Denn diese Länge ist möglicherweise nicht verfügbar! Von der docs :

Wenn eine von Stream abgeleitete Klasse das Suchen nicht unterstützt, lösen Aufrufe von Length, SetLength, Position und Seek eine NotSupportedException aus.

74voto

Joshua Punkte 3375

MemoryStream hat .WriteTo(outstream);

und .NET 4.0 hat .CopyTo für ein normales Stream-Objekt.

.NET 4.0:

instream.CopyTo(outstream);

33voto

Eloff Punkte 19617

Ich verwende die folgenden Erweiterungsmethoden. Sie haben optimierte Überladungen für den Fall, dass ein Stream ein MemoryStream ist.

    public static void CopyTo(this Stream src, Stream dest)
    {
        int size = (src.CanSeek) ? Math.Min((int)(src.Length - src.Position), 0x2000) : 0x2000;
        byte[] buffer = new byte[size];
        int n;
        do
        {
            n = src.Read(buffer, 0, buffer.Length);
            dest.Write(buffer, 0, n);
        } while (n != 0);           
    }

    public static void CopyTo(this MemoryStream src, Stream dest)
    {
        dest.Write(src.GetBuffer(), (int)src.Position, (int)(src.Length - src.Position));
    }

    public static void CopyTo(this Stream src, MemoryStream dest)
    {
        if (src.CanSeek)
        {
            int pos = (int)dest.Position;
            int length = (int)(src.Length - src.Position) + pos;
            dest.SetLength(length); 

            while(pos < length)                
                pos += src.Read(dest.GetBuffer(), pos, length - pos);
        }
        else
            src.CopyTo((Stream)dest);
    }

3voto

Jayesh Sorathia Punkte 1558

NET Framework 4 führt die neue Methode "CopyTo" der Stream-Klasse des System.IO-Namensraums ein. Mit dieser Methode können wir einen Stream in einen anderen Stream einer anderen Stream-Klasse kopieren.

Hier ein Beispiel dafür.

    FileStream objFileStream = File.Open(Server.MapPath("TextFile.txt"), FileMode.Open);
    Response.Write(string.Format("FileStream Content length: {0}", objFileStream.Length.ToString()));

    MemoryStream objMemoryStream = new MemoryStream();

    // Copy File Stream to Memory Stream using CopyTo method
    objFileStream.CopyTo(objMemoryStream);
    Response.Write("<br/><br/>");
    Response.Write(string.Format("MemoryStream Content length: {0}", objMemoryStream.Length.ToString()));
    Response.Write("<br/><br/>");

2voto

hannasm Punkte 1853

Es gibt tatsächlich eine weniger schwerfällige Methode, eine Stream-Kopie zu erstellen. Beachten Sie jedoch, dass dies voraussetzt, dass Sie die gesamte Datei im Speicher ablegen können. Versuchen Sie dies nicht, wenn Sie mit Dateien arbeiten, die Hunderte von Megabyte oder mehr groß sind, und seien Sie vorsichtig.

public static void CopySmallTextStream(Stream input, Stream output)
{
  using (StreamReader reader = new StreamReader(input))
  using (StreamWriter writer = new StreamWriter(output))
  {
    writer.Write(reader.ReadToEnd());
  }
}

HINWEIS: Es kann auch einige Probleme mit Binärdaten und Zeichenkodierungen geben.

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