2013-03-27 15 views
7

Ho due istanze MemoryStream.Come unire due flussi di memoria?

Come unirli in un'istanza?

Bene, ora non riesco a copiare da un MemoryStream all'altro. Ecco un metodo:

public static Stream ZipFiles(IEnumerable<FileToZip> filesToZip) { 
ZipStorer storer = null; 
     MemoryStream result = null; 
     try { 
      MemoryStream memory = new MemoryStream(1024); 
      storer = ZipStorer.Create(memory, GetDateTimeInRuFormat()); 
      foreach (var currentFilePath in filesToZip) { 
       string fileName = Path.GetFileName(currentFilePath.FullPath); 
       storer.AddFile(ZipStorer.Compression.Deflate, currentFilePath.FullPath, fileName, 
           GetDateTimeInRuFormat()); 
      } 
      result = new MemoryStream((int) storer.ZipFileStream.Length); 
      storer.ZipFileStream.CopyTo(result); //Does not work! 
               //result's length will be zero 
     } 
     catch (Exception) { 
     } 
     finally { 
      if (storer != null) 
       storer.Close(); 
     } 
     return result; 
    } 
+6

Che cosa significa "unire" significa? – Jon

+5

Questo è * vago *. Cosa stai cercando di fare? Esempio di codice? – Rob

+1

Perché è down down? Questo è molto intuitivo, -1 Robuust e -1 Jon. Un'istanza è quando si assegna una classe. L'oggetto in questione è un flusso di memoria (che è una matrice cercabile di byte, come un file in memoria). Inserire due file all'interno di un file di archivio (zip) ha senso. Combinare i bit di due file in quello che sembra uno e avere la possibilità di separarli è facile da capire. Quelle sono le tue uniche opzioni. post scriptum dare un po 'al ragazzo per aggiornare la risposta, se non ha senso. – TamusJRoyce

risposta

36

Spettacolarmente facile con CopyTo o CopyToAsync:

var streamOne = new MemoryStream(); 
FillThisStreamUp(streamOne); 
var streamTwo = new MemoryStream(); 
DoSomethingToThisStreamLol(streamTwo); 
streamTwo.CopyTo(streamOne); // streamOne holds the contents of both 

il quadro, la gente. La struttura .

+3

Assicurati di regolare le posizioni per l'operazione di copia, la posizione di StreamOne deve essere uguale alla sua lunghezza e la posizione di StreamTwo deve essere 0. – VMh

+0

@amit grazie, ma no grazie. Dovresti aggiungere una nuova risposta con il tuo codice. – Will

0
  • Crea terzo (lascia che sia mergedStream) MemoryStream con lunghezza uguale a riassumere di prime e seconde lunghezze

  • scrivere i primi MemoryStream a mergedStream (utilizzare GetBuffer() per get byte[] da MemoryStream)

  • Scrivi secondo MemoryStream a mergedStream (usa GetBuffer())

  • Ricordarsi di offset durante la scrittura.

E 'piuttosto accoda, ma è del tutto chiaro che cosa si fondono operazione su MemoryStreams

1

Sulla base della risposta condivisa da @Will sopra, qui è il codice completo:

void Main() 
{ 
    var s1 = GetStreamFromString("Hello"); 
    var s2 = GetStreamFromString(" World"); 

    var s3 = s1.Append(s2); 
    Console.WriteLine(Encoding.UTF8.GetString((s3 as MemoryStream).ToArray())); 
} 

public static Stream GetStreamFromString(string text) 
{ 
     MemoryStream stream = new MemoryStream(); 
     StreamWriter writer = new StreamWriter(stream); 
     writer.Write(text); 
     writer.Flush(); 
     stream.Position = 0; 

     return stream; 
} 

public static class Extensions 
{ 
    public static Stream Append(this Stream destination, Stream source) 
    { 
     destination.Position = destination.Length; 
     source.CopyTo(destination); 

     return destination; 
    } 
} 

e la fusione di raccolta ruscello con async:

async Task Main() 
{ 
    var list = new List<Task<Stream>> { GetStreamFromStringAsync("Hello"), GetStreamFromStringAsync(" World") }; 

    Stream stream = await list 
      .Select(async item => await item) 
      .Aggregate((current, next) => Task.FromResult(current.Result.Append(next.Result))); 

    Console.WriteLine(Encoding.UTF8.GetString((stream as MemoryStream).ToArray())); 
} 

public static Task<Stream> GetStreamFromStringAsync(string text) 
{ 
    MemoryStream stream = new MemoryStream(); 
    StreamWriter writer = new StreamWriter(stream); 
    writer.Write(text); 
    writer.Flush(); 
    stream.Position = 0; 

    return Task.FromResult(stream as Stream); 
} 

public static class Extensions 
{ 
    public static Stream Append(this Stream destination, Stream source) 
    { 
     destination.Position = destination.Length; 
     source.CopyTo(destination); 

     return destination; 
    } 
}