All formats

SharpCompress

LanguageC# (.NET Framework 4.8, .NET Standard 2.0/2.1, .NET 6, 8 and 10)
LicenseMIT
Repositorygithub.com/adamhathcock/sharpcompress
DocumentationUSAGE.md, FORMATS.md
Depends onnothing (pure managed code)
Read / writeyes / yes; reads LZMA, LZMA2, PPMd, BZip2, Deflate, BCJ, BCJ2 and AES-encrypted archives; writes non-solid LZMA/LZMA2 archives

SharpCompress is a managed library for many archive and compression formats: 7z, ZIP, RAR, TAR, GZip, BZip2, XZ, LZip and Zstandard. It has 3 APIs: Archive (random access to entries, needs a seekable stream), Reader (forward-only stream) and Writer.

For 7z only the Archive API reads, because the 7z header is at the end of the file and the format can’t be read as a forward-only stream. Writing uses SevenZipWriter, which needs a seekable output stream and produces non-solid archives with LZMA or LZMA2 and an LZMA-compressed header. Writing encrypted archives is not in the 0.50 stable release (it’s in the 0.51 betas).

The examples use the API of SharpCompress 0.50: methods are named OpenArchive, OpenReader and OpenWriter (older versions used Open).

Installation#

Shell
dotnet add package SharpCompress

Basic usage: list and extract a 7z archive#

C#
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Common;

using var archive = SevenZipArchive.OpenArchive("archive.7z");

Console.WriteLine($"solid: {archive.IsSolid}, entries: {archive.Entries.Count()}");
foreach (var entry in archive.Entries.Where(e => !e.IsDirectory))
{
    Console.WriteLine($"{entry.Key}  {entry.Size} bytes  {entry.LastModifiedTime}");
}

archive.WriteToDirectory("output", new ExtractionOptions
{
    ExtractFullPath = true,
    Overwrite = true,
});

WriteToDirectory extracts entries in archive order, which matters for solid archives: each solid block is decompressed once.

How to read a file from a 7z archive into memory#

C#
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;

using var archive = SevenZipArchive.OpenArchive("archive.7z");
var entry = archive.Entries.First(e => e.Key == "docs/readme.txt");

using var stream = entry.OpenEntryStream();
using var reader = new StreamReader(stream);
string text = reader.ReadToEnd();

In a solid archive, opening an entry in the middle of a block decompresses the data before it. To process all files, loop in archive order or use archive.ExtractAllEntries(), which returns a forward-only IReader.

How to open a password-protected 7z archive#

C#
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Common;
using SharpCompress.Readers;

var options = new ReaderOptions { Password = "secret" };
using var archive = SevenZipArchive.OpenArchive("secret.7z", options);
archive.WriteToDirectory("output", new ExtractionOptions { ExtractFullPath = true, Overwrite = true });

Archives with an encrypted header (file names hidden) need the password already in OpenArchive. A wrong password usually shows up as a CRC or data error during extraction.

How to create a 7z archive#

C#
using SharpCompress.Common;
using SharpCompress.Writers;
using SharpCompress.Writers.SevenZip;

using Stream output = File.Create("backup.7z");  // must be seekable
using var writer = WriterFactory.OpenWriter(
    output,
    ArchiveType.SevenZip,
    new SevenZipWriterOptions(CompressionType.LZMA2) { CompressHeader = true });

// a single file from a stream
using (var source = File.OpenRead("report.pdf"))
{
    writer.Write("docs/report.pdf", source, DateTime.UtcNow);
}

// a whole folder, recursively
writer.WriteAll("photos", "*", SearchOption.AllDirectories);

The 7z header is written when the writer is disposed, so keep the using blocks.

How to check if a file is a 7z archive#

C#
using SharpCompress.Archives.SevenZip;

bool is7z = SevenZipArchive.IsSevenZipFile("download.bin");  // checks the signature

ArchiveFactory.OpenArchive(path) detects the format automatically when you accept any archive type.

Tips#