2010-07-09 15 views
40

Ich habe den folgenden Konstruktor, der eine MemoryStream aus einem Dateipfad öffnet:Wie bekomme ich einen MemoryStream von einem Stream in .NET?

MemoryStream _ms; 

public MyClass(string filePath) 
{ 
    byte[] docBytes = File.ReadAllBytes(filePath); 
    _ms = new MemoryStream(); 
    _ms.Write(docBytes, 0, docBytes.Length); 
} 

Ich muss dies eine Stream anstelle eines Dateipfad zu akzeptieren ändern. Was ist der einfachste/effizienteste Weg, um ein MemoryStream vom Stream Objekt zu bekommen?

+3

Sobald Sie den Stream haben, warum umwandeln es in einen MemoryStream? Kannst du nicht einfach direkt mit dem Stream arbeiten? –

+1

Ich brauche einen MemoryStream wegen anderer Abhängigkeiten. – fearofawhackplanet

Antwort

18

Wenn Sie Ihre Klasse so ändern, dass sie anstelle eines Dateinamens einen Stream akzeptiert, sollten Sie nicht in einen MemoryStream konvertieren. Lassen Sie den zugrunde liegenden Stream die benötigten Operationen handhaben:

public class MyClass 
{ 
    Stream _s; 

    public MyClass(Stream s) { _s = s; } 
} 

Aber wenn Sie wirklich einen Memorystream für interne Operationen benötigen, müssen Sie die Daten aus dem Quellstrom in die Memory kopieren müssen:

public MyClass(Stream stream) 
{ 
    _ms = new MemoryStream(); 
    CopyStream(stream, _ms); 
} 

// Merged From linked CopyStream below and Jon Skeet's ReadFully example 
public static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[16*1024]; 
    int read; 
    while((read = input.Read (buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write (buffer, 0, read); 
    } 
} 
+0

Ich nehme an, dass am Ende der While-Zeile '> 0' steht? – fearofawhackplanet

+0

@fearofawhackplanet - Richtig. Ich habe ein wenig gelöscht glücklich. Fest. –

+3

sieht aus wie eine schließende Klammer fehlt. sollte 'while sein ((read = input.Read (buffer, 0, buffer.Length))> 0)' –

1
public static void Do(Stream in) 
{ 
    _ms = new MemoryStream(); 
    byte[] buffer = new byte[65536]; 
    while ((int read = input.Read(buffer, 0, buffer.Length))>=0) 
     _ms.Write (buffer, 0, read); 
} 
3

Sie müssen alle Daten aus dem Stream-Objekt in einen byte[] Puffer einlesen und dann über seinen Konstruktor in den MemoryStream übergeben. Es ist möglicherweise besser, genauer auf den Typ des Stream-Objekts einzugehen, das Sie verwenden. Stream ist sehr generisch und implementiert möglicherweise nicht das Length Attribut, das beim Einlesen von Daten sehr nützlich ist.

Hier ist ein Code für Sie:

public MyClass(Stream inputStream) { 
    byte[] inputBuffer = new byte[inputStream.Length]; 
    inputStream.Read(inputBuffer, 0, inputBuffer.Length); 

    _ms = new MemoryStream(inputBuffer); 
} 

Wenn das Stream Objekt das Length Attribut nicht implementiert, müssen Sie so etwas wie dies umzusetzen:

public MyClass(Stream inputStream) { 
    MemoryStream outputStream = new MemoryStream(); 

    byte[] inputBuffer = new byte[65535]; 
    int readAmount; 
    while((readAmount = inputStream.Read(inputBuffer, 0, inputBuffer.Length)) > 0) 
     outputStream.Write(inputBuffer, 0, readAmount); 

    _ms = outputStream; 
} 
1

Ich benutze diese Kombination aus Erweiterungsmethoden:

public static Stream Copy(this Stream source) 
    { 
     if (source == null) 
      return null; 

     long originalPosition = -1; 

     if (source.CanSeek) 
      originalPosition = source.Position; 

     MemoryStream ms = new MemoryStream(); 

     try 
     { 
      Copy(source, ms); 

      if (originalPosition > -1) 
       ms.Seek(originalPosition, SeekOrigin.Begin); 
      else 
       ms.Seek(0, SeekOrigin.Begin); 

      return ms; 
     } 
     catch 
     { 
      ms.Dispose(); 
      throw; 
     } 
    } 

    public static void Copy(this Stream source, Stream target) 
    { 
     if (source == null) 
      throw new ArgumentNullException("source"); 
     if (target == null) 
      throw new ArgumentNullException("target"); 

     long originalSourcePosition = -1; 
     int count = 0; 
     byte[] buffer = new byte[0x1000]; 

     if (source.CanSeek) 
     { 
      originalSourcePosition = source.Position; 
      source.Seek(0, SeekOrigin.Begin); 
     } 

     while ((count = source.Read(buffer, 0, buffer.Length)) > 0) 
      target.Write(buffer, 0, count); 

     if (originalSourcePosition > -1) 
     { 
      source.Seek(originalSourcePosition, SeekOrigin.Begin); 
     } 
    } 
148

In .NET 4, Sie kann Stream.CopyTo verwenden, um einen Stream anstelle der in den anderen Antworten aufgelisteten Methoden zu kopieren.

MemoryStream _ms; 

public MyClass(Stream sourceStream) 

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

verwenden:

var memoryStream = new MemoryStream(); 
stream.CopyTo(memoryStream); 

Dies wird Stream zu MemoryStream konvertieren.

Verwandte Themen