Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Zipping up files from a MemoryStream

July 18, 2016
dotnet

Recently I needed to write some .NET code that zipped up some files and downloaded the zip without touching the file system. I struggled to find a good example, so I thought I’d post the code here …

Assuming that we’ve got the source files in memory in the following structure:

public class SourceFile
{
    public string Name { get; set; }
    public string Extension { get; set; }
    public Byte[] FileBytes { get; set; }
}

We can use the following code to zip these files up and send the zip in the response:

public ActionResult Index()
{
    // get the source files
    List<SourceFile> sourceFiles = new List<SourceFile>();
    // ...

    // the output bytes of the zip
    byte[] fileBytes = null;

    // create a working memory stream
    using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
    {
        // create a zip
        using (System.IO.Compression.ZipArchive zip = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, true))
        {
            // interate through the source files
            foreach (SourceFile f in sourceFiles)
            {
                // add the item name to the zip
                System.IO.Compression.ZipArchiveEntry zipItem = zip.CreateEntry(f.Name + "." + f.Extension);
                // add the item bytes to the zip entry by opening the original file and copying the bytes
                using (System.IO.MemoryStream originalFileMemoryStream = new System.IO.MemoryStream(f.FileBytes))
                {
                    using (System.IO.Stream entryStream = zipItem.Open())
                    {
                        originalFileMemoryStream.CopyTo(entryStream);
                    }
                }
            }
        }
        fileBytes = memoryStream.ToArray();
    }

    // download the constructed zip
    Response.AddHeader("Content-Disposition", "attachment; filename=download.zip");
    return File(fileBytes, "application/zip");
}

Comments

himabindu.todupunuri April 18, 2018

I have used this able to add the byte[] files to the zip file, but when when unzipping the zip file and trying to open the files in it it is showing as ‘The archive is either in unknown format or damaged’.

Kinalkumar r patel May 21, 2018

I face same issue after using this code. Did you found any other solution?

Umesh July 27, 2018

I am also facing same issue.’Zip file is damaged

kasun February 8, 2019

var compressedFileStream = new MemoryStream();

using (compressedFileStream)
{
    //compressedFileStream.Seek(0, SeekOrigin.Begin);
    using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, false))
    {
        foreach (var caseAttachmentModel in archiveDataSet)
        {
            //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);
                }
            }
        }
    }
}
zipthis = compressedFileStream.ToArray();

taigrom September 26, 2018

Thanks so much! It works perfectly!!!

Rob October 12, 2018

This gives an error unless you change ZipArchiveMode to Update


timaxapa _January 25, 2019 _

Do not forget to set the stream position to the beginning before usages:

memoryStream .Seek(0, SeekOrigin.Begin);

Jenia November 7, 2019

had to change to Response.Headers.Add(..) and worked perfectly! thanks!

If you to learn about using React with ASP.NET Core you might find my book useful:

ASP.NET Core 5 and React

ASP.NET Core 5 and React
Find out more