MetaGuru
MetaGuru

Reputation: 43873

How to create and fill a ZIP file using ASP.NET?

Need to dynamically package some files into a .zip to create a SCORM package, anyone know how this can be done using code? Is it possible to build the folder structure dynamically inside of the .zip as well?

Upvotes: 27

Views: 49140

Answers (9)

Code
Code

Reputation: 749

#region Create zip file in asp.net c#
        string DocPath1 = null;/*This varialble is Used for Craetting  the File path .*/
        DocPath1 = Server.MapPath("~/MYPDF/") + ddlCode.SelectedValue + "/" + txtYear.Value + "/" + ddlMonth.SelectedValue + "/";
        string[] Filenames1 = Directory.GetFiles(DocPath1);
        using (ZipFile zip = new ZipFile())
        {
            zip.AddFiles(Filenames, "Pdf");//Zip file inside filename
            Response.Clear();
            Response.BufferOutput = false;
            string zipName = String.Format("Zip_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
            Response.ContentType = "application/zip";
            Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
            zip.Save(Response.OutputStream);
            Response.End();
        }
        #endregion

Upvotes: 0

Cheeso
Cheeso

Reputation: 192627

DotNetZip is nice for this.

You can write the zip directly to the Response.OutputStream. The code looks like this:

    Response.Clear();
    Response.BufferOutput = false; // for large files...
    System.Web.HttpContext c= System.Web.HttpContext.Current;
    String ReadmeText= "Hello!\n\nThis is a README..." + DateTime.Now.ToString("G"); 
    string archiveName= String.Format("archive-{0}.zip", 
                                      DateTime.Now.ToString("yyyy-MMM-dd-HHmmss")); 
    Response.ContentType = "application/zip";
    Response.AddHeader("content-disposition", "filename=" + archiveName);

    using (ZipFile zip = new ZipFile())
    {
        // filesToInclude is an IEnumerable<String>, like String[] or List<String>
        zip.AddFiles(filesToInclude, "files");            

        // Add a file from a string
        zip.AddEntry("Readme.txt", "", ReadmeText);
        zip.Save(Response.OutputStream);
    }
    // Response.End();  // no! See http://stackoverflow.com/questions/1087777
    Response.Close();

DotNetZip is free.

Upvotes: 22

Darkseal
Darkseal

Reputation: 9564

If you're using .NET Framework 4.5 or newer you can avoid third-party libraries and use the System.IO.Compression.ZipArchive native class.

Here’s a quick code sample using a MemoryStream and a couple of byte arrays representing two files:

byte[] file1 = GetFile1ByteArray();
byte[] file2 = GetFile2ByteArray();

using (MemoryStream ms = new MemoryStream())
{
    using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        var zipArchiveEntry = archive.CreateEntry("file1.txt", CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file1, 0, file1.Length);
        zipArchiveEntry = archive.CreateEntry("file2.txt", CompressionLevel.Fastest);
        using (var zipStream = zipArchiveEntry.Open()) zipStream.Write(file2, 0, file2.Length);
    }
    return File(ms.ToArray(), "application/zip", "Archive.zip");
}

You can use it inside a MVC Controller returning an ActionResult: alternatively, if you need to phisically create the zip archive, you can either persist the MemoryStream to disk or entirely replace it with a FileStream.

For further info regarding this topic you can also read this post on my blog.

Upvotes: 11

Hasiya
Hasiya

Reputation: 1458

Able to do this using DotNetZip. you can download it from the visual studio Nuget package manger or directly via the DotnetZip. then try below code,

     /// <summary>
    /// Generate zip file and save it into given location
    /// </summary>
    /// <param name="directoryPath"></param>
    public void CreateZipFile(string directoryPath )
    {
        //Select Files from given directory
        List<string> directoryFileNames = Directory.GetFiles(directoryPath).ToList();
        using (ZipFile zip = new ZipFile())
        {
            zip.AddFiles(directoryFileNames, "");
            //Generate zip file folder into loation
            zip.Save("C:\\Logs\\ReportsMyZipFile.zip");
        }
    }

If you want to download the file into client,use below code.

/// <summary>
    /// Generate zip file and download into client
    /// </summary>
    /// <param name="directoryPath"></param>
    /// <param name="respnse"></param>
    public void CreateZipFile(HttpResponse respnse,string directoryPath )
    {
        //Select Files from given directory
        List<string> directoryFileNames = Directory.GetFiles(directoryPath).ToList();
        respnse.Clear();
        respnse.BufferOutput = false;
        respnse.ContentType = "application/zip";
        respnse.AddHeader("content-disposition", "attachment; filename=MyFiles.zip");

        using (ZipFile zip = new ZipFile())
        {
            zip.CompressionLevel = CompressionLevel.None;
            zip.AddFiles(directoryFileNames, "");
            zip.Save(respnse.OutputStream);
        }

        respnse.flush();
    }

Upvotes: 1

user1228
user1228

Reputation:

You don't have to use an external library anymore. System.IO.Packaging has classes that can be used to drop content into a zip file. Its not simple, however. Here's a blog post with an example (its at the end; dig for it).


The link isn't stable, so here's the example Jon provided in the post.

using System;
using System.IO;
using System.IO.Packaging;

namespace ZipSample
{
    class Program
    {
        static void Main(string[] args)
        {
            AddFileToZip("Output.zip", @"C:\Windows\Notepad.exe");
            AddFileToZip("Output.zip", @"C:\Windows\System32\Calc.exe");
        }

        private const long BUFFER_SIZE = 4096;

        private static void AddFileToZip(string zipFilename, string fileToAdd)
        {
            using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
            {
                string destFilename = ".\\" + Path.GetFileName(fileToAdd);
                Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
                if (zip.PartExists(uri))
                {
                    zip.DeletePart(uri);
                }
                PackagePart part = zip.CreatePart(uri, "",CompressionOption.Normal);
                using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
                {
                    using (Stream dest = part.GetStream())
                    {
                        CopyStream(fileStream, dest);
                    }
                }
            }
        }

        private static void CopyStream(System.IO.FileStream inputStream, System.IO.Stream outputStream)
        {
            long bufferSize = inputStream.Length < BUFFER_SIZE ? inputStream.Length : BUFFER_SIZE;
            byte[] buffer = new byte[bufferSize];
            int bytesRead = 0;
            long bytesWritten = 0;
            while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                outputStream.Write(buffer, 0, bytesRead);
                bytesWritten += bytesRead;
            }
        }
    }
}

Upvotes: 17

Bala
Bala

Reputation: 31

DotNetZip is very easy to use... Creating Zip files in ASP.Net

Upvotes: 3

Jan Šotola
Jan Šotola

Reputation: 852

Creating ZIP file "on the fly" would be done using our Rebex ZIP component.

The following sample describes it fully, including creating a subfolder:

// prepare MemoryStream to create ZIP archive within
using (MemoryStream ms = new MemoryStream())
{
    // create new ZIP archive within prepared MemoryStream
    using (ZipArchive zip = new ZipArchive(ms))
    {            
         // add some files to ZIP archive
         zip.Add(@"c:\temp\testfile.txt");
         zip.Add(@"c:\temp\innerfile.txt", @"\subfolder");

         // clear response stream and set the response header and content type
         Response.Clear();
         Response.ContentType = "application/zip";
         Response.AddHeader("content-disposition", "filename=sample.zip");

         // write content of the MemoryStream (created ZIP archive) to the response stream
         ms.WriteTo(Response.OutputStream);
    }
}

// close the current HTTP response and stop executing this page
HttpContext.Current.ApplicationInstance.CompleteRequest();

Upvotes: 0

Macros
Macros

Reputation: 7119

I have used a free component from chilkat for this: http://www.chilkatsoft.com/zip-dotnet.asp. Does pretty much everything I have needed however I am not sure about building the file structure dynamically.

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1039378

You could take a look at SharpZipLib. And here's a sample.

Upvotes: 7

Related Questions