2010-07-09 4 views
40

J'ai la méthode constructeur suivante qui ouvre un MemoryStream à partir d'un chemin de fichier:Comment obtenir un MemoryStream à partir d'un flux dans .NET?

MemoryStream _ms; 

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

Je dois changer cela pour accepter un Stream au lieu d'un chemin de fichier. Quel est le moyen le plus simple/le plus efficace d'obtenir un MemoryStream à partir de l'objet Stream?

+3

Une fois que vous avez le Stream, pourquoi la convertir en MemoryStream? Tu ne peux pas travailler directement avec le Stream? –

+1

J'ai besoin d'un MemoryStream en raison d'autres dépendances. – fearofawhackplanet

Répondre

18

Si vous modifiez votre classe pour accepter un flux au lieu d'un nom de fichier, ne prenez pas la peine de convertir en MemoryStream. Laissez le flux sous-jacent gérer les opérations:

public class MyClass 
{ 
    Stream _s; 

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

Mais si vous avez vraiment besoin d'un MemoryStream pour les opérations internes, vous devrez copier les données de la source dans le flux 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

Je présume que c'est '> 0' à la fin de la ligne while? – fearofawhackplanet

+0

@fearofawhackplanet - Correct. J'ai eu un petit effacement heureux. Fixé. –

+3

ressemble à une parenthèse de fermeture manquante. devrait être '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

Vous devrez lire dans toutes les données de l'objet Stream dans un buffer byte[], puis le passer dans le MemoryStream via son constructeur. Il peut être préférable d'être plus précis sur le type d'objet que vous utilisez. Stream est très générique et ne peut pas implémenter l'attribut Length, ce qui est plutôt utile lors de la lecture de données.

Voici un code pour vous:

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

    _ms = new MemoryStream(inputBuffer); 
} 

Si l'objet Stream ne met pas en œuvre l'attribut Length, vous devrez mettre en œuvre quelque chose comme ceci:

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

J'utilise cette combinaison de méthodes d'extension:

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, vous pouvez utiliser Stream.CopyTo pour copier un flux, au lieu des méthodes de brassage à la maison énumérées dans les autres réponses.

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

Utilisez ceci:

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

Cela convertira Stream à MemoryStream.

Questions connexes