it-swarm.com.de

Zip-Datei aus Byte erstellen []

Ich versuche, eine Zip-Datei in .NET 4.5 (System.IO.Compression) aus einer Reihe von Byte-Arrays zu erstellen. Als Beispiel erhalte ich von einer API, die ich verwende, ein List<Attachment> und jedes Attachment hat eine Eigenschaft namens Body, die ein byte[]. Wie kann ich diese Liste durchlaufen und eine Zip-Datei erstellen, die jeden Anhang enthält?

Im Moment habe ich den Eindruck, dass ich jeden Anhang auf die Festplatte schreiben und daraus die Zip-Datei erstellen müsste.

//This is great if I had the files on disk
ZipFile.CreateFromDirectory(startPath, zipPath);
//How can I create it from a series of byte arrays?
45

Nachdem ich ein wenig herumgespielt und gelesen hatte, konnte ich das herausfinden. So können Sie eine Zip-Datei (Archiv) mit mehreren Dateien erstellen, ohne temporäre Daten auf die Festplatte zu schreiben:

using (var compressedFileStream = new MemoryStream())
//Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, false)) {
    foreach (var caseAttachmentModel in caseAttachmentModels) {
        //Create a Zip entry for each attachment
        var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);

        //Get the stream of the attachment
        using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body))
        using (var zipEntryStream = zipEntry.Open()) {
            //Copy the attachment stream to the Zip entry stream
            originalFileStream.CopyTo(zipEntryStream);
        }
    }

    return new FileContentResult(compressedFileStream.ToArray(), "application/Zip") { FileDownloadName = "Filename.Zip" };
}
80

Dies ist eine Variation der großen akzeptierten Antwort des OP. Dies gilt jedoch für WebForms anstelle von MVC. Ich arbeite mit der Annahme, dass caseAttachmentModel.Body ein Byte ist []

Im Wesentlichen ist alles dasselbe, mit Ausnahme einer zusätzlichen Methode, die die Zip-Datei als Antwort sendet.

using (var compressedFileStream = new MemoryStream()) {
    //Create an archive and store the stream in memory.
    using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))         {
     foreach (var caseAttachmentModel in caseAttachmentModels) {
        //Create a Zip entry for each attachment
        var zipEntry = zipArchive.CreateEntry(caseAttachmentModel.Name);

        //Get the stream of the attachment
        using (var originalFileStream = new MemoryStream(caseAttachmentModel.Body)) {
                using (var zipEntryStream = zipEntry.Open()) {
                    //Copy the attachment stream to the Zip entry stream
                    originalFileStream.CopyTo(zipEntryStream);
                }
            }
        }
    }
    sendOutZIP(compressedFileStream.ToArray(), "FileName.Zip");
}

private void sendOutZIP(byte[] zippedFiles, string filename)
{
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/x-compressed";
    Response.Charset = string.Empty;
    Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
    Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
    Response.BinaryWrite(zippedFiles);
    Response.OutputStream.Flush();
    Response.OutputStream.Close();
    Response.End();
}

Ich möchte auch darauf hinweisen, dass der Rat von @Levi Fuller zu Referenzen in der akzeptierten Antwort genau richtig ist!

4
ShinyCy

Mit GZipStream und DeflateStream können Sie anscheinend Steams/Byte-Arrays verwenden, um Ihr Problem zu lösen, möglicherweise jedoch nicht mit einem Komprimierungsdateiformat, das von den meisten Benutzern verwendet werden kann. (dh Ihre Datei hätte die Erweiterung .gz) Wenn diese Datei nur intern verwendet wird, ist dies möglicherweise in Ordnung.

Ich weiß nicht, wie Sie mit den Bibliotheken von Microsoft eine Zip-Datei erstellen können, aber ich erinnere mich, dass diese Bibliothek die Dinge unterstützt, die Sie möglicherweise nützlich finden: http://sevenzipsharp.codeplex.com/

Es ist unter der LGPL lizenziert.

2
Katana314