2010-07-09 22 views
40

Ho il seguente metodo di costruzione che si apre un MemoryStream da un percorso di file:Come ottenere un MemoryStream da uno streaming in .NET?

MemoryStream _ms; 

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

ho bisogno di cambiare questo per accettare una Stream invece di un percorso di file. Qual è il modo più semplice/più efficace per ottenere un MemoryStream dall'oggetto Stream?

+3

Una volta che hai lo Stream, perché preoccuparti di convertirlo in un MemoryStream? Non puoi lavorare direttamente con lo Stream? –

+1

Ho bisogno di un MemoryStream a causa di altre dipendenze. – fearofawhackplanet

risposta

18

Se stai modificando la tua classe per accettare uno Stream invece di un nome file, non preoccuparti di convertirlo in un MemoryStream. Lasciate che il flusso sottostante gestire le operazioni:

public class MyClass 
{ 
    Stream _s; 

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

Ma se si ha realmente bisogno di un MemoryStream per le operazioni interne, dovrete copiare i dati dal flusso di fonti in MemoryStream:

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

Suppongo che sia '> 0' alla fine della linea? – fearofawhackplanet

+0

@fearofawhackplanet - Corretto. Ho un po 'di cancellazione felice. Fisso. –

+3

sembra che manchi una parentesi chiusa. dovrebbe essere 'while ((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

Dovrai leggere tutti i dati dall'oggetto Stream in un buffer byte[] e quindi passarlo nello MemoryStream tramite il suo costruttore. Potrebbe essere meglio essere più specifici sul tipo di oggetto stream che si sta utilizzando. Stream è molto generico e potrebbe non implementare l'attributo Length, che è piuttosto utile durante la lettura dei dati.

Ecco un po 'di codice per voi:

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

    _ms = new MemoryStream(inputBuffer); 
} 

Se l'oggetto Stream non implementa l'attributo Length, si dovrà implementare qualcosa di simile:

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

Io uso questa combinazione di metodi di estensione:

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, si possibile utilizzare Stream.CopyTo per copiare uno stream, anziché i metodi home-brew elencati nelle altre risposte.

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

Utilizzare questa:

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

Questo convertirà Stream a MemoryStream.

Problemi correlati