30

How can I add some file (almost always a single .csv file) to an existing zip file?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
user3408397
  • 523
  • 1
  • 5
  • 14

3 Answers3

35

Since you are in .NET 4.5, you can use the ZipArchive (System.IO.Compression) class to achieve this. Here is the MSDN documentation: (MSDN).

Here is their example, it just writes text, but you could read in a .csv file and write it out to your new file. To just copy the file in, you would use CreateFileFromEntry, which is an extension method for ZipArchive.

using (FileStream zipToOpen = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.Open))
{
   using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update))
   {
       ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt");
       using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
       {
           writer.WriteLine("Information about this package.");
           writer.WriteLine("========================");
       }
   }
}
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Man, That was fast! I'll give this a try and see what happens. Thanks for posting so fast! I'll let you know if/when I have success with this. Nick – user3408397 Mar 12 '14 at 00:12
  • 1
    You'd be surprised, I've seen answers within 30 seconds to a minute of a post (for easy to answer questions of course). – BradleyDotNET Mar 12 '14 at 00:15
  • I am trying your suggestion Lord Takkera but I see a "snag". I am using the below: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.IO.Compression; using System.Diagnostics; The "ZipArchive" has a red underline. – user3408397 Mar 12 '14 at 00:19
  • The `ZipArchive` class was [added in .NET 4.5](http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx). – CodeCaster Mar 12 '14 at 00:27
  • Make sure you have a project reference to System.IO.Compression, and that you are using .NET 4.5 (you should since you are on VS 2012). – BradleyDotNET Mar 12 '14 at 00:29
  • Any chance you could elaborate on 'You could probably even find a way to just copy it in'? That is exactly what I need but I can't get it to work. – Mike Dymond Nov 04 '14 at 17:28
  • 1
    @MikeDymond You would use the `CreateEntryFromFile` method: http://msdn.microsoft.com/en-us/library/hh485720(v=vs.110).aspx If you wanted to post a new quesiton, I'd be happy to provide a code sample. I don't feel that this use case is all that important to *this* question. – BradleyDotNET Nov 04 '14 at 17:32
  • @BradleyDotNET Thanks for that. I had tried that before but hadn't realised that CreateEntryFromFile is in a DIFFERENT assembly to the ZipArchive object. Once I added that reference it worked no problem. – Mike Dymond Nov 04 '14 at 17:56
  • 1
    Also, check out ZipFileExtensions.CreateEntryFromFile – Guy L Feb 11 '15 at 20:11
34

For creating, extracting, and opening zip archives, we can use ZipFile Class with reference: System.IO.Compression.FileSystem. For .NET 4.5.2 and below, we also need to add reference: System.IO.Compression. Here's the method for adding files to zip:

    public static void AddFilesToZip(string zipPath, string[] files)
    {
        if (files == null || files.Length == 0)
        {
            return;
        }

        using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Update))
        {
            foreach (var file in files)
            {
                var fileInfo = new FileInfo(file);
                zipArchive.CreateEntryFromFile(fileInfo.FullName,  fileInfo.Name);
            }
        }
    }
tomRedox
  • 28,092
  • 24
  • 117
  • 154
Feiyu Zhou
  • 4,344
  • 32
  • 36
  • Thank you for this answer which I agree is much cleaner and neater. However, I struggled a little bit at first until I realised this answer requires a reference System.IO.Compression.Filesystem (not just System.IO.Compression). Thanks. – Rask Jul 17 '18 at 13:02
  • @FeiyuZhou, could you suggest how to add a folder and then the files. – Binoy Cherian Nov 30 '18 at 10:28
  • @BinoyCherian you can modify the code in `foreach` to support folder by using `CreateEntryFromFolder` method – Feiyu Zhou Nov 30 '18 at 11:46
  • Finally some accurate, complete info about ZipFile! Thanks. – Steve Jun 01 '20 at 21:03
  • Don't be confused, if you don't find the `CreateEntryFromFile` at the documentation of the [ZipFile](https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.zipfile) class. This method, and two other useful ones (`ExtractToDirectory` and `ExtractToFile`) are defined namely as extension methods in the [ZipFileExtensions](https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.zipfileextensions) class. – pholpar Sep 11 '21 at 05:45
  • For something like CreateEntryFromFolder to work we need to add Val's [extension class here](https://stackoverflow.com/questions/15133626/creating-directories-in-a-ziparchive-c-sharp-net-4-5). It implements a `CreateEntryFromDirectory` method and work recursively just fine.. – TaW Apr 18 '22 at 12:38
7

The easiest way is to get DotNetZip at http://dotnetzip.codeplex.com/

Adding files can be as easy as

String[] filenames = { @"ReadMe.txt",
                       @"c:\data\collection.csv" ,
                       @"c:\reports\AnnualSummary.pdf"
                     } ;
using ( ZipFile zip = new ZipFile() )
{
  zip.AddFiles(filenames);
  zip.Save("Archive.zip");
}

Other sorts of updates are just as trivial:

using (ZipFile zip = ZipFile.Read("ExistingArchive.zip"))
{

  // update an existing item in the zip file
  zip.UpdateItem("Portfolio.doc"); 

  // remove an item from the zip file
  zip["OldData.txt"].RemoveEntry();

  // rename an item in the zip file
  zip["Internationalization.doc"].FileName = "i18n.doc";

  // add a comment to the archive
  zip.Comment = "This zip archive was updated " + System.DateTime.ToString("G");

  zip.Save();
}

Edited To Note: DotNetZip used to live at Codeplex. Codeplex has been shut down. The old archive is still [available at Codeplex][1]. It looks like the code has migrated to Github:


Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135