-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Complete API documentation for ZARSharp. All types are in the ZARSharp namespace unless otherwise noted.
| Namespace | Contents |
|---|---|
ZARSharp |
Archive reader/writer, format structures, tool |
ZARSharp.Zstd |
zstd encoder/decoder, compression options |
ZARSharp.Seekable |
Seekable zstd format (Foot + Head) |
ZARSharp.Pipeline |
Pipeline engine, batch operations, progress |
Writes .zar archive files. Faithful port of zarchivewriter.cpp.
// Stream-based (recommended)
public ZArchiveWriter(Stream output, IZarBlockCompressor? compressor = null)
// Callback-based (for advanced scenarios)
public ZArchiveWriter(
Action<int> newOutputFile,
Action<byte[], int, int> writeOutputData,
IZarBlockCompressor? compressor = null)public void StartNewFile(string path)Begins writing a new file entry. Path is relative to the archive root, using / or \ as separators.
Parameters:
-
path— Relative file path (e.g.,"readme.txt","data/config.json")
Exceptions:
-
InvalidOperationException— If already writing a file -
ArgumentException— If path is empty or invalid
public void AppendData(ReadOnlySpan<byte> data)Appends data to the current file. Data is buffered and compressed in 64 KiB blocks.
Parameters:
-
data— Bytes to append
Exceptions:
-
InvalidOperationException— If no file is being written
public void Finalize()Writes the archive footer and SHA-256 integrity hash. Must be called after all files are written.
Exceptions:
-
InvalidOperationException— If already finalized
public void Dispose()Releases resources. Automatically calls Finalize() if not already done.
using var output = File.Create("archive.zar");
using var writer = new ZArchiveWriter(output);
writer.StartNewFile("readme.txt");
writer.AppendData("Hello, World!"u8);
writer.StartNewFile("data/binary.dat");
writer.AppendData(binaryData);
writer.Finalize();Reads .zar archive files. Faithful port of zarchivereader.h.
public static ZArchiveReader? TryOpen(string path)
public static ZArchiveReader? TryOpen(Stream stream, bool leaveOpen = false)Opens an archive. Returns null on invalid archives (never throws).
Parameters:
-
path— Archive file path -
stream— Archive stream -
leaveOpen— Keep stream open after reader disposal
Returns: Reader instance, or null if invalid
| Property | Type | Description |
|---|---|---|
InvalidNode |
uint |
Constant 0xFFFFFFFF for path-not-found |
public bool FileExists(string path)Checks if a file exists at the given path.
public bool DirectoryExists(string path)Checks if a directory exists at the given path.
public byte[] ReadFile(string path)Reads and decompresses an entire file.
Parameters:
-
path— File path within the archive
Returns: File contents
Exceptions:
-
FileNotFoundException— If file not found -
InvalidOperationException— If archive is corrupt
public byte[] ReadFileRange(string path, long offset, long length)Reads a range of bytes from a file.
Parameters:
-
path— File path within the archive -
offset— Byte offset within the file -
length— Number of bytes to read
Returns: Requested byte range
public IReadOnlyList<ZArchiveReader.DirEntry> ReadDirectory(string path)Lists directory contents.
Parameters:
-
path— Directory path within the archive
Returns: List of directory entries
public string GetName(uint nameIndex)Retrieves a name by its index in the name table.
public readonly struct DirEntry
{
public string Name { get; } // Entry name
public bool IsFile { get; } // True for files
public bool IsDirectory { get; } // True for directories
public ulong Size { get; } // File size (0 for directories)
}The reader is thread-safe for concurrent reads (single lock, like the C++ mutex).
using var reader = ZArchiveReader.TryOpen("archive.zar");
if (reader == null)
{
Console.WriteLine("Invalid archive");
return;
}
// List root directory
foreach (var entry in reader.ReadDirectory("/"))
{
Console.WriteLine($"{entry.Name}: {(entry.IsFile ? $"{entry.Size} bytes" : "DIR")}");
}
// Read a file
byte[] data = reader.ReadFile("readme.txt");High-level pack/extract operations. Port of main.cpp CLI behavior.
public static void Pack(
string inputDirectory,
string? outputFile = null,
Action<string>? progress = null,
IZarBlockCompressor? compressor = null,
bool deterministicOrder = true)Packs a directory into a .zar file.
Parameters:
-
inputDirectory— Directory to pack (recursively) -
outputFile— Destination path, ornullfor<stem>.zar -
progress— Optional per-file callback (relative path) -
compressor— Block compressor, ornullfor default (zstd level 6) -
deterministicOrder—true(default) sorts entries ordinally
Exceptions:
-
IOException— On I/O errors or when refusing to overwrite -
InvalidOperationException— On archive structure errors
public static void Extract(string inputFile, string outputDirectory)Extracts an archive to a directory.
Parameters:
-
inputFile— Archive file path -
outputDirectory— Destination directory (created if needed)
Exceptions:
-
IOException— On I/O errors -
InvalidOperationException— On corrupt archives
Interface for custom block compressors.
public interface IZarBlockCompressor
{
int Compress(ReadOnlySpan<byte> source, Span<byte> destination);
}Returns: Compressed size, or -1 to store the block raw (uncompressed).
Built-in compressor that stores every block raw (no compression).
public sealed class ZarRawCompressor : IZarBlockCompressorOptions for the zstd compressor.
| Property | Type | Default | Description |
|---|---|---|---|
Level |
int |
6 |
Compression level (1–22) |
ChecksumFlag |
bool |
false |
Write 4-byte XXH64 content checksum |
public static ZstdCompressionOptions FromLevel(int level)Creates options for the specified level (1–22).
Pure-C# zstd encoder. Implements IZarBlockCompressor.
public ZstdCompressor(ZstdCompressionOptions? options = null)| Property | Type | Description |
|---|---|---|
Options |
ZstdCompressionOptions |
Active options |
public int Compress(ReadOnlySpan<byte> source, Span<byte> destination)Compresses source as a single-shot frame. Returns frame size, or -1 when the frame would not fit or would not be smaller.
public byte[] CompressBlock(ReadOnlySpan<byte> source)Compresses and returns the frame as a new byte array.
public static int GetCompressBound(int sourceSize)Returns the maximum possible compressed size for a given input size.
public static byte[] DecompressFrame(ReadOnlySpan<byte> src, int maxSize)Decompresses a zstd frame.
Parameters:
-
src— Frame bytes -
maxSize— Maximum allowed decompressed size
Returns: Decompressed data
Compression strategy selector. Maps to libzstd's ZSTD_strategy.
| Value | Name | Typical Levels |
|---|---|---|
1 |
Fast |
1 |
2 |
DoubleFast |
2–3 |
3 |
Greedy |
4–5 |
4 |
Lazy |
6–7 |
5 |
Lazy2 |
8–9 |
6 |
BtLazy2 |
10–12 |
7 |
BtOpt |
13–15 |
8 |
BtUltra |
16–18 |
9 |
BtUltra2 |
19–22 |
Writes seekable zstd files with Foot/Head seek tables.
public SeekableWriter(SeekableOptions? options = null)| Property | Type | Description |
|---|---|---|
SeekTable |
SeekTable |
Current seek table (frames logged so far) |
public void Write(ReadOnlySpan<byte> data)Appends data, emitting full frames as needed.
public byte[] Finish()Finalizes and returns the complete seekable file bytes.
public byte[] FinishHead()Returns just the seek table as a standalone Head frame.
Reads seekable zstd files.
// Parse embedded Foot table
public SeekableReader(byte[] data)
// Use external seek table (e.g., standalone Head)
public SeekableReader(byte[] data, SeekTable table)| Property | Type | Description |
|---|---|---|
Table |
SeekTable |
Parsed seek table |
DecompressedLength |
long |
Total decompressed size |
FrameCount |
int |
Number of frames |
public byte[] DecompressAll()Decompresses the entire payload.
public byte[] DecompressRange(long offset, long length)Decompresses a byte range, decoding only the frames the range touches.
| Exception | Namespace | When Thrown |
|---|---|---|
ZarArchiveOpenException |
ZARSharp.Pipeline |
Archive fails to open |
ZarInputOpenException |
ZARSharp.Pipeline |
Input file cannot be opened |
ZarEntryCreateException |
ZARSharp.Pipeline |
Archive entry creation fails |
ZstdException |
ZARSharp.Zstd |
zstd decompression error |
IOException |
System |
I/O errors |
InvalidOperationException |
System |
Invalid state (corrupt archive, etc.) |
try
{
ZArchiveTool.Extract("corrupt.zar", "output");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"Corrupt archive: {ex.Message}");
}
catch (IOException ex)
{
Console.WriteLine($"I/O error: {ex.Message}");
}// TryOpen never throws — returns null on invalid archives
using var reader = ZArchiveReader.TryOpen("maybe-valid.zar");
if (reader == null)
{
Console.WriteLine("Invalid or corrupt archive");
return;
}ZArchiveSharp
Getting Started
Core Concepts
API
Advanced
Links