Compression and Archives

Vaibhav • September 10, 2025

As applications grow in complexity and scale, they often need to manage large amounts of data - logs, backups, configuration files, or even entire folders. Storing and transferring this data efficiently becomes critical. That’s where compression and archiving come in. In this article, we’ll explore how to compress and decompress files in C#, how to work with ZIP archives, and how to integrate these capabilities into real-world workflows like backups, packaging, and deployment.

Understanding Compression vs Archiving

Compression reduces the size of a file by encoding its contents more efficiently. Archiving bundles multiple files into a single container. ZIP files do both - they compress and archive. Other formats like TAR (used in Unix) only archive, while GZIP only compresses a single file.

In C#, the System.IO.Compression namespace provides built-in support for working with ZIP and GZIP formats. These tools are fast, reliable, and cross-platform.

Compression is especially useful when transferring files over a network, storing backups, or reducing disk usage. ZIP archives are widely supported and easy to integrate.

Creating a ZIP Archive

To create a ZIP archive from a folder, use ZipFile.CreateFromDirectory. This method compresses all files and subfolders into a single ZIP file.

using System.IO.Compression;

string sourceFolder = "Reports";
string zipPath = "ReportsBackup.zip";

ZipFile.CreateFromDirectory(sourceFolder, zipPath);

This creates ReportsBackup.zip containing all files from the Reports folder. If the ZIP file already exists, it will be overwritten.

Extracting a ZIP Archive

To extract a ZIP file, use ZipFile.ExtractToDirectory. This decompresses all contents into a target folder.

string zipPath = "ReportsBackup.zip";
string extractFolder = "RestoredReports";

ZipFile.ExtractToDirectory(zipPath, extractFolder);

This restores the original folder structure and files. If the target folder doesn’t exist, it will be created automatically.

Always extract ZIP files to a dedicated folder to avoid overwriting existing files or mixing contents.

Adding Files to an Existing ZIP

To add files to an existing ZIP archive, use ZipArchive with ZipArchiveMode.Update. This lets you open the archive and insert new entries.

using System.IO;
using System.IO.Compression;

using FileStream zipToOpen = new FileStream("ReportsBackup.zip", FileMode.Open);
using ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update);

archive.CreateEntryFromFile("summary.txt", "summary.txt");

This adds summary.txt to the ZIP file. The second parameter is the name it will have inside the archive.

Reading Files from a ZIP Archive

You can also read files directly from a ZIP archive without extracting them. This is useful for previewing contents or processing files on the fly.

using FileStream zipToOpen = new FileStream("ReportsBackup.zip", FileMode.Open);
using ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read);

foreach (ZipArchiveEntry entry in archive.Entries)
{
    Console.WriteLine($"Found: {entry.FullName} ({entry.Length} bytes)");
}

This lists all files in the archive along with their sizes. You can also open each entry as a stream and read its contents.

Compressing a Single File with GZip

If you only need to compress a single file (not archive), use GZipStream. This creates a .gz file that contains the compressed data.

using FileStream originalFile = new FileStream("data.txt", FileMode.Open);
using FileStream compressedFile = new FileStream("data.txt.gz", FileMode.Create);
using GZipStream compressionStream = new GZipStream(compressedFile, CompressionMode.Compress);

originalFile.CopyTo(compressionStream);

This compresses data.txt into data.txt.gz. The original file remains unchanged.

Decompressing a GZip File

To decompress a .gz file, reverse the process using CompressionMode.Decompress:

using FileStream compressedFile = new FileStream("data.txt.gz", FileMode.Open);
using FileStream decompressedFile = new FileStream("data_restored.txt", FileMode.Create);
using GZipStream decompressionStream = new GZipStream(compressedFile, CompressionMode.Decompress);

decompressionStream.CopyTo(decompressedFile);

This restores the original contents to data_restored.txt. GZip is ideal for compressing logs, backups, or large text files.

Choosing Compression Level

You can control the trade-off between speed and compression ratio using CompressionLevel:

  • Fastest - quick compression, larger files
  • Optimal - slower, better compression
  • NoCompression - just archiving, no size reduction
using FileStream output = new FileStream("data.gz", FileMode.Create);
using GZipStream gzip = new GZipStream(output, CompressionLevel.Optimal);

This gives you control over performance and file size. Use Fastest for real-time scenarios, and Optimal for backups.

Working with Streams and Archives

You can combine streams and compression to build flexible pipelines. For example, compressing a file while reading it from memory:

byte[] data = File.ReadAllBytes("input.txt");

using MemoryStream inputStream = new MemoryStream(data);
using FileStream outputFile = new FileStream("compressed.gz", FileMode.Create);
using GZipStream gzip = new GZipStream(outputFile, CompressionMode.Compress);

inputStream.CopyTo(gzip);

This compresses data from memory without touching the disk. You can also decompress into memory for fast access.

Handling Exceptions

Compression operations can fail due to missing files, permission issues, or corrupted archives. Always wrap your logic in try-catch blocks:

try
{
    ZipFile.CreateFromDirectory("Logs", "Logs.zip");
}
catch (IOException ex)
{
    Console.WriteLine($"Compression failed: {ex.Message}");
}

This ensures your app handles errors gracefully and provides useful feedback.

Real-World Use Case: Daily Backup

Let’s build a simple backup routine that compresses a folder with a timestamp:

string source = "Logs";
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string zipName = $"LogsBackup_{timestamp}.zip";

ZipFile.CreateFromDirectory(source, zipName);
Console.WriteLine($"Backup created: {zipName}");

This creates a uniquely named ZIP file for each backup. You can schedule this using a timer or a background service.

Summary

Compression and archiving are essential tools for managing data efficiently in C#. You’ve learned how to create and extract ZIP files, compress single files with GZip, read and update archives, and build flexible pipelines using streams. These techniques are useful for backups, deployments, packaging, and performance optimization. In the next article, we’ll explore CSV file processing - how to read, parse, and write structured tabular data using simple and powerful patterns.