All formats

System.IO.Compression

LanguageC# / .NET
LicenseMIT (part of .NET)
Repositorygithub.com/dotnet/runtime
DocumentationZipFile, ZipArchive
Depends onnothing (built into .NET; zlib-ng is bundled in the runtime)
Read / writeyes / yes, ZIP64, stored and DEFLATE (reads Deflate64); no encryption

System.IO.Compression is part of .NET and .NET Framework 4.5+. It has three classes:

It handles ZIP64 and UTF-8 names automatically. It can’t read or write password-protected archives; use SharpZipLib or SharpCompress for those. .NET 10 adds async versions (ZipFile.OpenReadAsync, ExtractToDirectoryAsync, ZipArchiveEntry.OpenAsync…).

Installation#

Nothing to install on .NET (Core) and .NET 5+. On .NET Framework, reference the System.IO.Compression and System.IO.Compression.FileSystem assemblies.

Basic usage: create and extract a ZIP#

C#
using System.IO.Compression;

// zip a whole folder (the folder itself is not included, only its contents)
ZipFile.CreateFromDirectory("photos", "photos.zip", CompressionLevel.Optimal, includeBaseDirectory: false);

// unzip into a folder, overwriting existing files
ZipFile.ExtractToDirectory("photos.zip", "out", overwriteFiles: true);

ExtractToDirectory throws an IOException for entries whose path would land outside the target folder, so it’s safe against Zip Slip.

How to list the files in a ZIP#

C#
using System;
using System.IO.Compression;

using ZipArchive archive = ZipFile.OpenRead("in.zip");
foreach (ZipArchiveEntry entry in archive.Entries)
{
    // directory entries have an empty Name and a FullName ending in '/'
    Console.WriteLine($"{entry.FullName,-40} {entry.Length,10} -> {entry.CompressedLength,10}  {entry.LastWriteTime}");
}

How to read one file from a ZIP without extracting#

C#
using System.IO;
using System.IO.Compression;

using ZipArchive archive = ZipFile.OpenRead("in.zip");
ZipArchiveEntry? entry = archive.GetEntry("docs/readme.txt");  // exact, case-sensitive name
if (entry != null)
{
    using Stream s = entry.Open();
    using var reader = new StreamReader(s);
    string text = reader.ReadToEnd();
    // or save it: entry.ExtractToFile("readme.txt", overwrite: true);
}

How to create a ZIP from files and strings#

C#
using System.IO;
using System.IO.Compression;

using (FileStream fs = File.Create("out.zip"))
using (var archive = new ZipArchive(fs, ZipArchiveMode.Create))
{
    archive.CreateEntryFromFile("report.pdf", "docs/report.pdf", CompressionLevel.SmallestSize);

    ZipArchiveEntry entry = archive.CreateEntry("hello.txt");
    using StreamWriter writer = new(entry.Open());
    writer.WriteLine("hello from .NET");
}

Create mode writes entries one after another and works with non-seekable streams (e.g. an HTTP response). Only one entry can be open for writing at a time.

How to add or delete files in an existing ZIP#

C#
using System.IO.Compression;

using ZipArchive archive = ZipFile.Open("existing.zip", ZipArchiveMode.Update);
archive.CreateEntryFromFile("new.txt", "new.txt");
archive.GetEntry("old.log")?.Delete();
// changes are written when the archive is disposed

Update mode loads entries into memory when you open them, so it’s slow for large archives.

Tips#