Create zip from multiple files in memory

riya picture riya · Mar 20, 2012 · Viewed 12.1k times · Source

I am trying to use SharpZipLib to generate zip file and let the client download it.

Currently zip folder is created and available on client machine but the issue is download.zip folder is blank. The files which are specified in a folder are not available in zip folder.

Below is the code I tried.

System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();

//stream directly to client.
ICSharpCode.SharpZipLib.Zip.ZipOutputStream output = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(response.OutputStream);
output.SetLevel(9);
string[] files =    Directory.GetFiles("D:/newfolder/");
for (int i = 0; i < files.Length; i++)
{
    ICSharpCode.SharpZipLib.Zip.ZipEntry entry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(files[i].ToString());
    entry.DateTime = DateTime.Now;
    System.IO.FileStream fs = new System.IO.FileStream(files[i].ToString(), FileMode.Open);      
    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, buffer.Length);
    entry.Size = fs.Length;
    fs.Close();
    crc.Reset();
    crc.Update(buffer);
    entry.Crc = crc.Value;
    output.PutNextEntry(entry);
    output.Write(buffer, 0, buffer.Length);
}

output.Finish();
output.Close();
response.Clear();
response.ContentType = "D:/Work Area/";
response.AddHeader("Content-Disposition", "attachment; filename=" + "download.zip");
response.End();

Can anyone tell me whats the issue? Why the files are not available in .zip

Answer

Abrian Stemmet picture Abrian Stemmet · Mar 20, 2012

After browsing the SharpDevelop wiki I found the following which may be of assistance to you in helping you resolve the problem:

using ICSharpCode.SharpZipLib.Zip;

// This will accumulate each of the files named in the fileList into a zip file,
// and stream it to the browser.
// This approach writes directly to the Response OutputStream.
// The browser starts to receive data immediately which should avoid timeout problems.
// This also avoids an intermediate memorystream, saving memory on large files.
//
private void DownloadZipToBrowser(List <string> zipFileList) 
{
    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[] buffer = new byte[4096];

    ZipOutputStream zipOutputStream = new ZipOutputStream(Response.OutputStream);
    zipOutputStream.SetLevel(3); //0-9, 9 being the highest level of compression

    foreach (string fileName in zipFileList) {

        Stream fs = File.OpenRead(fileName);    // or any suitable inputstream

        ZipEntry entry = new ZipEntry(ZipEntry.CleanName(fileName));
        entry.Size = fs.Length;
        // Setting the Size provides WinXP built-in extractor compatibility,
        //  but if not available, you can set zipOutputStream.UseZip64 = UseZip64.Off instead.

        zipOutputStream.PutNextEntry(entry);

        int count = fs.Read(buffer, 0, buffer.Length);
        while (count > 0) {
            zipOutputStream.Write(buffer, 0, count);
            count = fs.Read(buffer, 0, buffer.Length);
            if (!Response.IsClientConnected) {
                break;
            }
            Response.Flush();
        }
        fs.Close();
    }
    zipOutputStream.Close();

    Response.Flush();
    Response.End(); 
}