Creating Zip Files from Memory Stream C#

c#, memorystream, zip

Solution

This link describes how to create a zip from a MemoryStream using SharpZipLib: https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples#wiki-anchorMemory. Using this and iTextSharp, I was able to zip multiple PDF files that were created in memory.

Here is my code:

MemoryStream outputMemStream = new MemoryStream();
ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
byte[] bytes = null;

// loops through the PDFs I need to create
foreach (var record in records)
{
    var newEntry = new ZipEntry("test" + i + ".pdf");
    newEntry.DateTime = DateTime.Now;

    zipStream.PutNextEntry(newEntry);

    bytes = CreatePDF(++i);

    MemoryStream inStream = new MemoryStream(bytes);
    StreamUtils.Copy(inStream, zipStream, new byte[4096]);
    inStream.Close();
    zipStream.CloseEntry();
}

zipStream.IsStreamOwner = false;    // False stops the Close also Closing the underlying stream.
zipStream.Close();          // Must finish the ZipOutputStream before using outputMemStream.

outputMemStream.Position = 0;

return File(outputMemStream.ToArray(), "application/octet-stream", "reports.zip");

The CreatePDF Method:

private static byte[] CreatePDF(int i)
{
    byte[] bytes = null;
    using (MemoryStream ms = new MemoryStream())
    {
        Document document = new Document(PageSize.A4, 25, 25, 30, 30);
        PdfWriter writer = PdfWriter.GetInstance(document, ms);
        document.Open();
        document.Add(new Paragraph("Hello World " + i));
        document.Close();
        writer.Close();
        bytes = ms.ToArray();
    }

    return bytes;
}

Problem

Basically the user should be able to click on one link and download multiple pdf files. But the Catch is I cannot create files on server or anywhere. Everything has to be in memory. I was able to create memory stream and Response.Flush() it as pdf but how do I zip multiple memory streams without creating files. Here is my code: ``` Response.ContentType = "application/zip"; // If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that // Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer. Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\""); Response.CacheControl = "Private"; Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition byte[] abyBuffer = new byte[4096]; ZipOutputStream outStream = new ZipOutputStream(Response.OutputStream); outStream.SetLevel(3); #region Repeat for each Memory Stream MemoryStream fStream = CreateClassroomRoster();// This returns a memory stream with pdf document ZipEntry objZipEntry = new ZipEntry(ZipEntry.CleanName("ClassroomRoster.pdf")); objZipEntry.DateTime = DateTime.Now; objZipEntry.Size = fStream.Length; outStream.PutNextEntry(objZipEntry); int count = fStream.Read(abyBuffer, 0, abyBuffer.Length); while (count > 0) { outStream.Write(abyBuffer, 0, count); count = fStream.Read(abyBuffer, 0, abyBuffer.Length); if (!Response.IsClientConnected) break; Response.Flush(); } fStream.Close(); #endregion outStream.Finish(); outStream.Close(); Response.Flush(); Response.End(); ``` This creates a zip file but there's no file inside it I am using using iTextSharp.text - for creating pdf using ICSharpCode.SharpZipLib.Zip - for Zipping Thanks, Kavita

Original source