GitHub - kingsznhone/FastLZMA2Net: Fast LZMA2 Wrapper for .NET (original) (raw)
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.
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 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.
