SharpCompress
| Language | C# (.NET Framework 4.8, .NET Standard 2.0, .NET 8 and newer) |
|---|---|
| License | MIT |
| Repository | github.com/adamhathcock/sharpcompress |
| Documentation | USAGE.md, API.md |
| Depends on | nothing |
| Read / write | yes / no for RAR; RAR4 and RAR5, passwords (also encrypted headers), solid, multi-volume, SFX |
SharpCompress reads and writes many archive formats in pure managed code: ZIP, TAR, 7z, GZip, BZip2, XZ, Zstandard, and read-only RAR, ARJ and ACE. Its RAR decoder is an independent C# port, not a binding to native code, so it runs anywhere .NET runs.
It has 2 APIs. The Archive API (RarArchive) needs a seekable file or stream and gives random access to entries. The Reader API (ReaderFactory, RarReader) reads forward only, which works on network streams and is the fast way to go through solid archives. All operations have Async versions.
Installation#
dotnet add package SharpCompress
Basic usage: list and extract a RAR file#
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
using var archive = RarArchive.OpenArchive("archive.rar");
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 keeps solid archives fast.
How to read one file from a RAR into memory#
using SharpCompress.Archives.Rar;
using var archive = RarArchive.OpenArchive("archive.rar");
var entry = archive.Entries.First(e => e.Key == "docs/readme.txt");
using var input = entry.OpenEntryStream();
using var ms = new MemoryStream();
input.CopyTo(ms);
byte[] bytes = ms.ToArray();
In a solid archive, opening an entry in the middle decompresses all entries before it. Use the Reader API below when you need many entries.
How to extract a password-protected RAR#
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
using SharpCompress.Readers;
using var archive = RarArchive.OpenArchive(
"secret.rar",
ReaderOptions.ForFilePath.WithPassword("password"));
if (archive.IsEncrypted)
Console.WriteLine("archive is encrypted");
archive.WriteToDirectory("output", new ExtractionOptions { ExtractFullPath = true, Overwrite = true });
The same password decrypts file names when the archive has encrypted headers. A missing or wrong password throws SharpCompress.Common.CryptographicException.
How to extract a multi-volume RAR#
ArchiveFactory.GetFileParts finds the other volumes (.part2.rar, .r00, …) from the first one:
using SharpCompress.Archives;
var parts = ArchiveFactory.GetFileParts("movie.part1.rar")
.Select(path => new FileInfo(path))
.ToArray();
using var archive = ArchiveFactory.OpenArchive(parts);
archive.WriteToDirectory("output");
How to stream a RAR from a non-seekable stream#
The Reader API reads entries one by one from any stream, for example an HTTP response:
using SharpCompress.Readers;
using Stream stream = File.OpenRead("archive.rar"); // or a network stream
using var reader = ReaderFactory.OpenReader(stream);
while (reader.MoveToNextEntry())
{
if (reader.Entry.IsDirectory) continue;
Console.WriteLine(reader.Entry.Key);
using var entryStream = reader.OpenEntryStream();
// process entryStream, e.g. entryStream.CopyTo(destination)
}
reader.WriteEntryToDirectory("output") writes the current entry to disk instead.
Tips#
RarArchive.IsRarFile(path)checks the signature before opening.archive.IsCompleteis false when volumes are missing.CheckCrc = trueinExtractionOptionsverifies the CRC of every extracted file.