2010-07-09 18 views
40

Tengo el siguiente método constructor que abre una MemoryStream de una ruta de archivo:¿Cómo obtener un MemoryStream de un Stream en .NET?

MemoryStream _ms; 

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

tengo que cambiar esto a aceptar una Stream en lugar de una ruta de archivo. ¿Cuál es la forma más fácil/más eficiente de obtener un MemoryStream del objeto Stream?

+3

Una vez que tenga el flujo, ¿por qué molestarse en convertirlo en un MemoryStream? ¿No puedes simplemente trabajar con Stream directamente? –

+1

Necesito un MemoryStream debido a otras dependencias. – fearofawhackplanet

Respuesta

18

Si está modificando su clase para aceptar un Stream en lugar de un nombre de archivo, no se moleste en convertir a un MemoryStream. Dejar que el flujo subyacente manejar las operaciones de:

public class MyClass 
{ 
    Stream _s; 

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

Pero si realmente necesita un MemoryStream para las operaciones internas, que tendrá que copiar los datos de la corriente de origen en el 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

Supongo que es '> 0' al final de la línea de tiempo? – fearofawhackplanet

+0

@fearofawhackplanet - Correcto. Tengo un poco de eliminación feliz. Fijo. –

+3

parece que falta un paréntesis de cierre. debería ser '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

Deberá leer todos los datos del objeto Stream en un buffer byte[] y luego pasarlo al MemoryStream a través de su constructor. Puede ser mejor ser más específico sobre el tipo de objeto de secuencia que está utilizando. Stream es muy genérico y no puede implementar el atributo Length, que es bastante útil cuando se leen datos.

Aquí hay algo de código para usted:

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

    _ms = new MemoryStream(inputBuffer); 
} 

Si el objeto Stream no implementa el atributo Length, que tendrá que implementar algo como esto:

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

utilizo esta combinación de métodos de extensión:

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

En .NET 4, usted puede usar Stream.CopyTo para copiar una secuencia, en lugar de los métodos de elaboración casera enumerados en las otras respuestas.

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

Utilice esta:

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

Esto convertirá a StreamMemoryStream.

Cuestiones relacionadas