Créer un fichier zip à partir de l’octet

J’essaie de créer un fichier Zip dans .NET 4.5 (System.IO.Compression) à partir d’une série de tableaux d’octets. Par exemple, à partir d’une API que j’utilise, je me retrouve avec une List et chaque Attachment a une propriété appelée Body qui est un byte[] . Comment puis-je parcourir cette liste et créer un fichier zip contenant chaque pièce jointe?

En ce moment, j’ai l’impression que je devrais écrire chaque pièce jointe sur le disque et créer le fichier zip à partir de celui-ci.

 //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? 

Après avoir joué un peu plus et lu, j’ai pu comprendre cela. Voici comment créer un fichier zip (archive) avec plusieurs fichiers sans écrire de données temporaires sur le disque:

 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); } } return new FileContentResult(compressedFileStream.ToArray(), "application/zip") { FileDownloadName = "Filename.zip" }; } 

Ceci est une variante de la grande réponse acceptée envoyée par le PO. Cependant, ceci est pour WebForms au lieu de MVC. Je travaille avec l’hypothèse que caseAttachmentModel.Body est un octet []

Essentiellement, tout est identique sauf avec une méthode supplémentaire qui envoie le fichier zip en tant que réponse.

 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, ssortingng filename) { Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.ContentType = "application/x-compressed"; Response.Charset = ssortingng.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(); } 

Je tiens également à souligner que les conseils donnés par @Levi Fuller sur les références dans la réponse acceptée sont bien connus!

GZipStream et DeflateStream semblent vous permettre d’utiliser des tableaux steams / byte pour résoudre votre problème, mais peut-être pas avec un format de fichier de compression utilisable par la plupart des utilisateurs. (c.-à-d. que votre fichier aurait une extension .gz) Si ce fichier n’est utilisé qu’en interne, cela peut être correct.

Je ne sais pas comment vous pourriez créer un ZIP en utilisant les bibliothèques de Microsoft, mais je me souviens de cette bibliothèque qui supporte le genre de choses que vous pourriez trouver utiles: http://sevenzipsharp.codeplex.com/

Il est sous licence LGPL.