Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Zip Files from Memory Stream C#

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

like image 980
Arshya Avatar asked Apr 04 '12 13:04

Arshya


People also ask

How do I make an AZIP file?

To zip (compress) a file or folderLocate the file or folder that you want to zip. Press and hold (or right-click) the file or folder, select (or point to) Send to, and then select Compressed (zipped) folder. A new zipped folder with the same name is created in the same location.

Is zip64 lossless?

ZIP is an archive file format that supports lossless data compression.

How do I create a zip file in C++?

You can invoke C code from a C++ application. There are many references on the net, such as this one: parashift.com/c++-faq/mixing-c-and-cpp.html As for libzip itself, it is an external library. Read its man pages, starting here: nih.at/libzip/libzip.html Click the other functions for their man pages.


3 Answers

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;
}
like image 196
Kris Avatar answered Oct 13 '22 19:10

Kris


Below code is to get files from a directory in azure blob storage, merge in a zip and save it in azure blob storage again.

    var outputStream = new MemoryStream();
    var archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true);

    CloudBlobDirectory blobDirectory = appDataContainer.GetDirectoryReference(directory);
    
    var blobs = blobDirectory.ListBlobs();

    foreach (CloudBlockBlob blob in blobs)
    {
        var fileArchive = archive.CreateEntry(Path.GetFileName(blob.Name),CompressionLevel.Optimal);

        MemoryStream blobStream = new MemoryStream();
        if (blob.Exists())
        {
            blob.DownloadToStream(blobStream);
            blobStream.Position = 0;
        }

        var open = fileArchive.Open();
        blobStream.CopyTo(open);
        blobStream.Flush();
        open.Flush();
        open.Close();

        if (deleteBlobAfterUse)
        {
            blob.DeleteIfExists();
        }
    }
    archive.Dispose();

    CloudBlockBlob zipBlob = appDataContainer.GetBlockBlobReference(zipFile);

    zipBlob.UploadFromStream(outputStream);

Need the namespaces:

  • System.IO.Compression;
  • System.IO.Compression.ZipArchive;
  • Microsoft.Azure.Storage;
  • Microsoft.Azure.Storage.Blob;
like image 23
Guilherme Flores Avatar answered Oct 13 '22 21:10

Guilherme Flores


This code Will help You in Creating Zip by multiple pdf files which you will get Each file from a Download Link.

        using (var outStream = new MemoryStream())
                {
                    using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
                    {
                        for (String Url in UrlList)
                        {
                            WebRequest req = WebRequest.Create(Url);
                            req.Method = "GET";
                            var fileInArchive = archive.CreateEntry("FileName"+i+ ".pdf", CompressionLevel.Optimal);
                            using (var entryStream = fileInArchive.Open())
                            using (WebResponse response = req.GetResponse())
                            {
                                using (var fileToCompressStream = response.GetResponseStream())
                                {
                                    entryStream.Flush();
                                    fileToCompressStream.CopyTo(entryStream);
                                    fileToCompressStream.Flush();
                                }
                            }
                           i++;
                        }

                    }
                    using (var fileStream = new FileStream(@"D:\test.zip", FileMode.Create))
                    {
                        outStream.Seek(0, SeekOrigin.Begin);
                        outStream.CopyTo(fileStream);
                    }
                }

Namespace Needed: System.IO.Compression; System.IO.Compression.ZipArchive;

like image 1
Skull Avatar answered Oct 13 '22 19:10

Skull