SharpCompress
| Language | C# / .NET (.NET Framework 4.8, .NET Standard 2.0, .NET 6/8/10) |
|---|---|
| License | MIT |
| Repository | github.com/adamhathcock/sharpcompress |
| Documentation | USAGE.md, API.md |
| Depends on | nothing (pure managed code) |
| Read / write | yes / yes; reads stored, DEFLATE, Deflate64, bzip2, LZMA, PPMd, XZ, Zstandard and ZipCrypto / WinZip AES; writes stored, DEFLATE, bzip2, LZMA, PPMd, Zstandard, ZIP64 |
SharpCompress reads many archive formats (ZIP, RAR, 7z, tar, gzip, bzip2, xz, Zstandard and more) through one API, so code that extracts ZIP files also extracts RAR and 7z. It has two styles:
- the Archive API (
ZipArchive,ArchiveFactory): random access to entries; needs a seekable stream or a file. - the Reader / Writer API (
ReaderFactory,WriterFactory,ZipWriter): forward-only, works with non-seekable streams such as a download in progress.
All operations have async versions. Version 0.50 renamed the factory methods to OpenArchive, CreateArchive, OpenReader and OpenWriter; older examples on the web use Open and Create.
Installation#
dotnet add package SharpCompress
Basic usage: extract a ZIP file#
using System;
using System.Linq;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using (var archive = ZipArchive.OpenArchive("in.zip"))
{
foreach (var entry in archive.Entries.Where(e => !e.IsDirectory))
{
Console.WriteLine($"{entry.Key}: {entry.Size} bytes ({entry.CompressedSize} compressed)");
}
archive.WriteToDirectory(@"out", new ExtractionOptions
{
ExtractFullPath = true,
Overwrite = true,
});
}
ArchiveFactory.OpenArchive("file") does the same for any supported format, detected from the content.
How to create a ZIP file#
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using (var archive = ZipArchive.CreateArchive())
{
archive.AddEntry("readme.txt", @"C:\docs\readme.txt");
archive.AddAllFromDirectory(@"C:\photos");
archive.SaveTo("out.zip", CompressionType.Deflate);
}
How to write a ZIP to a stream entry by entry#
ZipWriter writes forward-only, so the output can be a network stream. Each entry can have its own compression method:
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.Writers.Zip;
using Stream output = File.Create("out.zip");
using var writer = new ZipWriter(output, new ZipWriterOptions(CompressionType.Deflate)
{
ArchiveComment = "made with SharpCompress",
});
using (Stream source = File.OpenRead("data.csv"))
{
writer.Write("data.csv", source, new ZipWriterEntryOptions
{
CompressionType = CompressionType.ZStandard,
CompressionLevel = 3,
ModificationDateTime = DateTime.UtcNow,
});
}
Set UseZip64 = true in ZipWriterOptions before writing entries that may reach 4 GiB to a non-seekable stream.
How to read a password-protected ZIP#
using SharpCompress.Archives.Zip;
using SharpCompress.Readers;
var options = ReaderOptions.ForEncryptedArchive("my password");
using var archive = ZipArchive.OpenArchive("secret.zip", options);
archive.WriteToDirectory(@"out");
Both ZipCrypto and WinZip AES are supported for reading. SharpCompress doesn’t create encrypted ZIP files.
How to read a ZIP from a non-seekable stream#
using System;
using System.IO;
using SharpCompress.Readers;
using Stream stream = File.OpenRead("in.zip"); // or a network stream
using var reader = ReaderFactory.OpenReader(stream);
while (reader.MoveToNextEntry())
{
if (reader.Entry.IsDirectory) continue;
Console.WriteLine(reader.Entry.Key);
using Stream entryStream = reader.OpenEntryStream();
// process entryStream
}
Tips#
- For archives with non-UTF-8 file names, set a decoder in
ReaderOptionswithWithArchiveEncoding(see USAGE.md). ArchiveFactory.IsArchive(path, out var type)detects the format without opening entries.ExtractionOptions.ExtractFullPath = falseflattens all files into one folder.