---
title: "Extract a tar.gz file in C#"
url: https://recursiveai.org/onearchive/cookbook/extract-tar-gz/
description: "Extract a .tar.gz file in C#: open a gzip-compressed tar archive, list it and extract it to a folder, with tar.xz, tar.zst and tar.bz2 the same way. Pure C#."
version: "1.0.0"
---

# Extract a tar.gz file in C#

Call `Archive.Extract` with the `.tar.gz` file and a target folder: the gzip layer and the tar inside are both handled. The program below extracts the zlib source release, a tar.gz you can download to try it.

```shell
dotnet new console -o ExtractTarGz && cd ExtractTarGz
dotnet add package RecursiveAI.OneArchive --version 1.0.0
curl -L -o zlib-1.3.1.tar.gz https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz
```

Put this in `Program.cs` and run `dotnet run`:

```csharp
using RecursiveAI.OneArchive;

using (var archive = Archive.Open("zlib-1.3.1.tar.gz"))
{
    Console.WriteLine($"{archive.Entries.Count} entries");
    foreach (var e in archive.Entries.Take(4))
        Console.WriteLine($"  {e.Kind,-9} {e.Size,7:N0}  {e.Name}");

    // Read one file without extracting the rest.
    using var readme = archive.OpenEntry(archive.Find("zlib-1.3.1/README")!);
    Console.WriteLine(new StreamReader(readme).ReadLine());
}

Archive.Extract("zlib-1.3.1.tar.gz", "src");
int count = Directory.GetFiles("src", "*", SearchOption.AllDirectories).Length;
Console.WriteLine($"extracted {count} files to src/");
```

```text
296 entries
  Directory       0  zlib-1.3.1
  Directory       0  zlib-1.3.1/.github
  Directory       0  zlib-1.3.1/.github/workflows
  File        2,402  zlib-1.3.1/.github/workflows/cmake.yml
ZLIB DATA COMPRESSION LIBRARY
extracted 257 files to src/
```

The format comes from the bytes, so `.tgz`, `.tar.xz`, `.tar.zst`, `.tar.bz2`, `.tar.lz4` and a plain `.tar` extract with the same call. Paths that would climb out of `src/` and links that point outside it are refused ([Extract untrusted archives safely](https://recursiveai.org/onearchive/cookbook/safe-extraction/)).

## Limits

- **Owners aren’t restored.** Permissions and modification times are (`RestorePermissions` and `RestoreTimes`, both on by default), but there is no `chown` from managed code; each entry still carries its owner ids and names.
- **Reading one file from a .tar.gz reads up to it.** gzip can’t seek, so `OpenEntry` decompresses the archive from the start; for many random reads, extract first or use zip.

To create a tar.gz, `Archive.Create("backup.tar.gz").Add("folder/").Save()` picks the format from the extension, as [Getting started](https://recursiveai.org/onearchive/docs/getting-started/) shows.
