2015-04-15 6 views
10

Ist es irgendwie möglich, ein ZipArchiv aus den Dateien im Speicher (und nicht tatsächlich auf der Festplatte) zu erstellen.Wie erstellt man ZipArchive aus Dateien im Speicher in C#?

Es folgt der Anwendungsfall: Mehrere Dateien werden in einem IEnumerable<HttpPostedFileBase> Variable empfangen. Ich möchte alle diese Dateien zusammen zippen ZipArchive. Das Problem ist, dass ZipArchive nur CreateEntryFromFile erlaubt, die einen Pfad zu der Datei erwartet, wo ich gerade die Dateien im Speicher habe.

Frage: Gibt es eine Möglichkeit, einen ‚Strom‘ zu verwenden, in ZipArchive den ‚Eintrag‘ zu schaffen, so dass ich direkt in dem Inhalt der Datei in der Zip setzen kann?

Ich möchte nicht zuerst die Dateien speichern, erstellen Sie die ZIP (aus den Pfaden der gespeicherten Dateien) und löschen Sie dann die einzelnen Dateien.

Hier attachmentFiles ist IEnumerable<HttpPostedFileBase>

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var attachment in attachmentFiles) 
     { 
      zipArchive.CreateEntryFromFile(Path.GetFullPath(attachment.FileName), Path.GetFileName(attachment.FileName), 
           CompressionLevel.Fastest); 
     } 
    } 
    ... 
} 
+3

Haben Sie versucht http://stackoverflow.com/questions/12347775/ziparchive- erstellt-invalid-zip-Datei/12350106 # 12350106? –

+0

Warum nicht eine temporäre Datei erstellen und dann freigeben, wenn das Archiv fertig ist? – RussDunn

+0

Ich möchte vermeiden, eine temporäre Datei zu erstellen und sie nachher zu löschen, wenn möglich. Das habe ich in der Frage geschrieben, aber wenn nicht anders, dann muss ich das tun. – Flair

Antwort

14

Ja, Sie können dies tun, die ZipArchive.CreateEntry Methode, wie @AngeloReis in den Kommentaren darauf hingewiesen, und beschrieben here für ein etwas anderes Problem.

Ihr Code würde dann wie folgt aussehen:

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var attachment in attachmentFiles) 
     { 
      var entry = zipArchive.CreateEntry(attachment.FileName, CompressionLevel.Fastest); 
      using (var entryStream = entry.Open()) 
      { 
       attachment.InputStream.CopyTo(entryStream); 
      } 
     } 
    } 
    ... 
} 
+2

Arbeitete wie ein Charme, danke! Ich benutzte es, um eine Zip-Datei einer Reihe von PDFs zu erstellen, die ich als Byte [] in der Datenbank gespeichert hatte. Keine Notwendigkeit, das Dateisystem überhaupt zu involvieren. Der Benutzer klickt auf eine Schaltfläche und die ZIP-Datei wird über ihren Webbrowser heruntergeladen. (BTW, im innersten "using" -Block habe ich stattdessen entryStream.Write (arrBytes, 0, arrBytes.Length); – ClearCloud8

+1

Was sind attachmentFiles? – Demodave

0

Zunächst einmal Dank @ Alex für die perfekte Antwort.
Auch für das Szenario müssen Sie von Dateisystemen lesen:

using (var ms = new MemoryStream()) 
{ 
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var file in filesAddress) 
     { 
      zipArchive.CreateEntryFromFile(file, Path.GetFileName(file)); 
     } 
    } 

    ... 
} 

mit Hilfe von System.IO.Compression.ZipFileExtensions

Verwandte Themen