9

I have a folder on my web server that has hundreds of mp3 files in it. I would like to provide the option for a user to download a zipped archive of every mp3 in the directory from a web page.

I want to compress the files programmatically only when needed. Because the zip file will be quite large, I am thinking that I will need to send the zip file to the response stream as it is being zipped, for performance reasons.

Is this possible? How can I do it?

Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • 1
    Once you get your answer, be sure to turn off compression when adding files to the zip file... Mp3 files dont compress very well.... –  Apr 19 '10 at 19:42
  • 1
    Of course, because they are already compressed. Thanks for the reminder. – Ronnie Overby Apr 19 '10 at 19:45

4 Answers4

12

Here is code I use to do this with DotNetZip - works very well. Obviously you will need to provide the variables for outputFileName, folderName, and includeSubFolders.

response.ContentType = "application/zip";
response.AddHeader("content-disposition", "attachment; filename=" + outputFileName);
using (ZipFile zipfile = new ZipFile()) {
  zipfile.AddSelectedFiles("*.*", folderName, includeSubFolders);
  zipfile.Save(response.OutputStream);
}
Ray
  • 21,485
  • 5
  • 48
  • 64
  • 2
    In case you don't want your directory subtree in the Zip Archive, simply use the method overload `zipfile.AddSelectedFiles("*.*", folderName, direcotryInZip, includeSubFolders);` – marquito Aug 20 '13 at 14:10
  • 1
    @marquito In fact, I think the accepted answer would be better if it had used that overload. – S. Dixon Sep 18 '14 at 20:08
  • 1
    hey Ray, I need one small help related to making zip files. IF you can help. do let me know here. It would be glad :) Thanks – Nad Jul 27 '17 at 09:32
  • 1
    What is your question? – Ray Jul 28 '17 at 15:11
  • 2
    what is the response here? It says response doesn't exist in the context. Tried WebResponse, HttpResponse, doesn't work – MSIslam Feb 20 '18 at 20:14
  • My code lives in an HttpHandler. 'response' comes from the HttpContext passed to ProcessRequest. – Ray Feb 21 '18 at 21:27
8

I can't believe how easy this was. After reading this, here is the code that I used:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Clear();
    Response.BufferOutput = false;
    Response.ContentType = "application/zip";
    Response.AddHeader("content-disposition", "attachment; filename=pauls_chapel_audio.zip");

    using (ZipFile zip = new ZipFile())
    {
        zip.CompressionLevel = CompressionLevel.None;
        zip.AddSelectedFiles("*.mp3", Server.MapPath("~/content/audio/"), "", false);
        zip.Save(Response.OutputStream);
    }

    Response.Close();
}
Community
  • 1
  • 1
Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • 1
    ZipFile zip = new ZipFile(), when I try to create, it shows "You cannot create an instance of static class ZipFile". I don't know why – Bimal Das Jun 28 '18 at 05:57
  • 3
    @BimalDas That's because the ZipFile class in my answer is from the DotNetZip library. You're project is referencing `System.IO.Compression.ZipFile`. – Ronnie Overby Jun 30 '18 at 10:22
2

You could add a custom handler (.ashx file) that takes the file path, reads the file compresses it using a compression library and returns the bytes to the end user with the correct content-type.

vfilby
  • 9,938
  • 9
  • 49
  • 62
1
            foreach (GridViewRow gvrow in grdUSPS.Rows)
            {
                  CheckBox chk = (CheckBox)gvrow.FindControl("chkSelect");
                if (chk.Checked)
                {
                string fileName = gvrow.Cells[1].Text;

                string filePath = Server.MapPathfilename);
                zip.AddFile(filePath, "files");
                }
            }
            Response.Clear();
            Response.AddHeader("Content-Disposition", "attachment; filename=DownloadedFile.zip");
            Response.ContentType = "application/zip";
            zip.Save(Response.OutputStream);
            Response.End();
Saiyam
  • 138
  • 2
  • 11