When it comes to compression of data, there are a number of options natively available on .NET

These are especially useful in scenarios where you are operating with streams, such as when serving files on a web server.

When it comes to compression, there are usually tradeoffs that you have to make between:

  • File size
  • Compression time
  • Processor usage

In .NET 11, a new algorithm has been introduced - Zstandard, also known as zstd.

This, like the others, is in the System.IO.Compression namespace.

For this demonstration, we will use a copy of our old friend, Leo Tolstoy’s tome, War and Peace.

We start by updating our .csproj to reference our file at the root of the project.

<ItemGroup>
  <None Include="war-and-peace.txt">
  	<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Next, we write code to compress the file using the 3 algorithms and the new zstd.

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

const string fileName = "war-and-peace.txt";
// Build path to store the files
var targetPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory!.FullName;

// ZStandard
await using (var inputStream = File.OpenRead(fileName))
{
    await using (var outputStream = File.Create(Path.Combine(targetPath, "ZStandard")))
    {
        await using (var compressStream = new ZstandardStream(outputStream, CompressionMode.Compress))
        {
            await inputStream.CopyToAsync(compressStream);
        }
    }
}

// Brotli
await using (var inputStream = File.OpenRead(fileName))
{
    await using (var outputStream = File.Create(Path.Combine(targetPath, "Brotli")))
    {
        await using (var compressStream = new BrotliStream(outputStream, CompressionMode.Compress))
        {
            await inputStream.CopyToAsync(compressStream);
        }
    }
}

// Gzip
await using (var inputStream = File.OpenRead(fileName))
{
    await using (var outputStream = File.Create(Path.Combine(targetPath, "Gzip")))
    {
        await using (var compressStream = new GZipStream(outputStream, CompressionMode.Compress))
        {
            await inputStream.CopyToAsync(compressStream);
        }
    }
}

// Deflate
await using (var inputStream = File.OpenRead(fileName))
{
    await using (var outputStream = File.Create(Path.Combine(targetPath, "Deflate")))
    {
        await using (var compressStream = new DeflateStream(outputStream, CompressionMode.Compress))
        {
            await inputStream.CopyToAsync(compressStream);
        }
    }
}

If we navigate to the output folder, we will see our files:

compressedFiles

We can view the sizes in detail in the console:

consoleFiles

We can see here that in decreasing size:

  1. ZStandard
  2. Brotli
  3. Deflate
  4. GZip

TLDR

.NET 11 has introduced the ZStandard compression algorithm in the System.IO.Compression namespace.

The code is in my GitHub.

Happy hacking!