C# classics: creating ZIP files with built-in .NET libraries

Posted: (EET/GMT+2)

 

Microsoft's .NET built-in class library can do many things for you, and today, we've looking at one classic function: creating zip files without any external libraries.

So, if you need to compress files into a ZIP archive from C#, you do not need a third-party library for the basic case: .NET includes ZIP support in the System.IO.Compression namespace.

The simplest option is to compress a whole folder:

using System.IO.Compression;

string sourceFolder = @"C:\Temp\Reports";
string zipFile = @"C:\Temp\Reports.zip";

ZipFile.CreateFromDirectory(sourceFolder,
    zipFile, CompressionLevel.Optimal,
    includeBaseDirectory: false);

This creates Reports.zip file from the files under C:\Temp\Reports.

The includeBaseDirectory parameter controls whether the folder itself is added as the top-level folder inside the ZIP file or not (here, not).

Note that the CreateFromDirectory method fails if the destination ZIP file already exists. In this case, delete the old file first if replacing it is what you want to do:

if (File.Exists(zipFile))
{
    File.Delete(zipFile);
}

ZipFile.CreateFromDirectory(sourceFolder,
    zipFile, CompressionLevel.Optimal,
    includeBaseDirectory: false);

If you need more control, use ZipArchive and add files manually.

using System.IO.Compression;

string zipFile = @"C:\Temp\SelectedFiles.zip";

string[] files =
{
    @"C:\Temp\Reports\January.txt",
    @"C:\Temp\Reports\February.txt",
    @"C:\Temp\Reports\March.txt"
};

if (File.Exists(zipFile))
{
    File.Delete(zipFile);
}

using FileStream zipStream = File.Create(zipFile);
using ZipArchive archive = new ZipArchiv(zipStream,
  ZipArchiveMode.Create);

foreach (string file in files)
{
    string entryName = Path.GetFileName(file);
    archive.CreateEntryFromFile(file,
        entryName, CompressionLevel.Optimal);
}

This is useful when you want to choose exactly which files are included, or when the ZIP entry names should be different from the original file paths.

For example, this stores files under a folder inside the archive:

string entryName = "reports/" + Path.GetFileName(file);

Remember that ZIP entry names should use forward slashes when creating folder paths inside the archive.

To extract a ZIP file, use ExtractToDirectory:

using System.IO.Compression;

string zipFile = @"C:\Temp\Reports.zip";
string extractFolder = @"C:\Temp\ExtractedReports";

ZipFile.ExtractToDirectory(zipFile, extractFolder);

Good default choices include:

  • use ZipFile.CreateFromDirectory for whole folders
  • use ZipArchive when selecting files manually
  • use CompressionLevel.Optimal for normal compression
  • delete or version the destination file before creating a new archive.

The classic ZIP compression helps most with text files, CSV files, JSON files, XML files, and logs. Already-compressed files such as JPEG, PNG, MP4, PDF, and existing ZIP files may not shrink much.