Project Awesome project awesome

FastLZMA2NET

A .NET Wrapper of Fast LZMA2 Algorithm. Write support for zip/tar/bzip2/gzip are implemented

Package 12 stars GitHub

FastLZMA2Net

Fast LZMA2 Compression algorithm Wrapper for .NET

⚠️This library is not designed to generate valid 7z archives; it is solely responsible for compressing and decompressing individual byte streams.

Change Log

With respect to Fast LZMA2 repo

Requirements

.NET 8 / .NET 10

OS Architectures
Windows x64 · x86 · arm64
Linux (glibc) x64 · x86 · arm64 · arm
Linux (musl / Alpine) x64 · arm64

x86 may have potential malfunction.

Installation

PM> Install-Package FastLZMA2Net

API Overview

Class Description
FL2 Static helpers — one-shot compress / decompress, memory estimation
Compressor Reusable compression context
Decompressor Reusable decompression context
CompressStream Streaming compression (Stream subclass)
DecompressStream Streaming decompression (Stream subclass)

Usage

Simple compression

byte[] origin       = File.ReadAllBytes(sourceFilePath);
byte[] compressed   = FL2.Compress(origin, level: 6);
byte[] decompressed = FL2.Decompress(compressed);

ReadOnlySpan<byte> overloads are available to avoid a copy when data is already in a pooled or stack-allocated buffer:

ReadOnlySpan<byte> span = ...;
byte[] compressed = FL2.Compress(span, level: 6);

Multi-threaded one-shot compression

byte[] compressed   = FL2.CompressMT(origin, level: 6, nbThreads: 0);  // 0 = all cores
byte[] decompressed = FL2.DecompressMT(compressed, nbThreads: 0);

Context Compression

Reuse a Compressor / Decompressor to amortize context-allocation cost across many calls (e.g. batches of small files).

using Compressor compressor = new(nbThreads: 0) { CompressLevel = 10 };
byte[] c1 = compressor.Compress(data1);
byte[] c2 = compressor.Compress(data2);

using Decompressor decompressor = new();
byte[] d1 = decompressor.Decompress(c1);
byte[] d2 = decompressor.Decompress(c2);

Async compression

using Compressor compressor = new(nbThreads: 0) { CompressLevel = 6 };
byte[] compressed = await compressor.CompressAsync(origin, cancellationToken);

using Decompressor decompressor = new();
byte[] decompressed = await decompressor.DecompressAsync(compressed, cancellationToken);

File-to-file compression (no memory copy)

Uses memory-mapped I/O — no full read into managed memory.

using Compressor compressor = new(nbThreads: 0) { CompressLevel = 6 };
nuint compressedBytes = compressor.Compress(sourceFilePath, destFilePath);

Streaming Compression

CompressStream is a writable Stream and DecompressStream is a readable Stream. Pipe any stream in or out via Write / CopyTo / CopyToAsync — there is no size restriction. The compress stream is finalised automatically when Dispose() is called.

Compress

// in-memory
using MemoryStream ms = new();
using (CompressStream cs = new(ms) { CompressLevel = 10 })
    cs.Write(origin);
byte[] compressed = ms.ToArray();

// file (works for any size)
using FileStream sourceFile     = File.OpenRead(sourceFilePath);
using FileStream compressedFile = File.Create(compressedFilePath);
using (CompressStream cs = new(compressedFile) { CompressLevel = 10 })
    sourceFile.CopyTo(cs);

Compress (async)

await using FileStream sourceFile     = File.OpenRead(sourceFilePath);
await using FileStream compressedFile = File.Create(compressedFilePath);
await using (CompressStream cs = new(compressedFile) { CompressLevel = 10 })
    await sourceFile.CopyToAsync(cs);

Decompress

// in-memory
using MemoryStream recoveryStream = new();
using (DecompressStream ds = new(new MemoryStream(compressed)))
    ds.CopyTo(recoveryStream);
byte[] decompressed = recoveryStream.ToArray();

// file (works for any size)
using FileStream compressedFile = File.OpenRead(compressedFilePath);
using FileStream recoveryFile   = File.Create(decompressedFilePath);
using (DecompressStream ds = new(compressedFile))
    ds.CopyTo(recoveryFile);

Fine-tune compression parameters

using Compressor compressor = new(nbThreads: 0) { CompressLevel = 10 };
compressor.SetParameter(FL2Parameter.FastLength, 48);
compressor.SetParameter(FL2Parameter.SearchDepth, 60);

Estimate memory usage

// By compression level and thread count
nuint size = FL2.EstimateCompressMemoryUsage(compressionLevel: 10, nbThreads: 8);

// Using an existing context's settings
using Compressor compressor = new(nbThreads: 4) { CompressLevel = 10 };
nuint size = FL2.EstimateCompressMemoryUsage(compressor.CompressLevel, compressor.ThreadCount);

Find decompressed size

// From a byte array
nuint size = FL2.FindDecompressedSize(compressedData);

// From a file path (uses memory-mapped I/O — no full read into memory)
nuint size = FL2.FindDecompressedSize(compressedFilePath);

Bug report

Open an issue.

Contribution

PR is welcome.

Back to .NET