Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create ZipArchive from files in memory in C#?

Tags:

Is it somehow possible to create a ZipArchive from the file(s) in memory (and not actually on the disk).

Following is the use case: Multiple files are received in an IEnumerable<HttpPostedFileBase> variable. I want to zip all these files together using ZipArchive. The problem is that ZipArchive only allows CreateEntryFromFile, which expects a path to the file, where as I just have the files in memory.

Question: Is there a way to use a 'stream' to create the 'entry' in ZipArchive, so that I can directly put in the file's contents in the zip?

I don't want to first save the files, create the zip (from the saved files' paths) and then delete the individual files.

Here, attachmentFiles is 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);         }     }     ... } 
like image 432
Flair Avatar asked Apr 15 '15 10:04

Flair


2 Answers

Yes, you can do this, using the ZipArchive.CreateEntry method, as @AngeloReis pointed out in the comments, and described here for a slightly different problem.

Your code would then look like this:

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);             }         }     }     ... } 
like image 198
Alex Avatar answered Oct 02 '22 02:10

Alex


First off thanks @Alex for the perfect answer.
Also for the scenario you need to read from file systems :

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));         }     }      ... } 

with the help of System.IO.Compression.ZipFileExtensions

like image 33
Soren Avatar answered Oct 02 '22 00:10

Soren