GzipSeekable 0.1.0
dotnet add package GzipSeekable --version 0.1.0
NuGet\Install-Package GzipSeekable -Version 0.1.0
<PackageReference Include="GzipSeekable" Version="0.1.0" />
<PackageVersion Include="GzipSeekable" Version="0.1.0" />
<PackageReference Include="GzipSeekable" />
paket add GzipSeekable --version 0.1.0
#r "nuget: GzipSeekable, 0.1.0"
#:package GzipSeekable@0.1.0
#addin nuget:?package=GzipSeekable&version=0.1.0
#tool nuget:?package=GzipSeekable&version=0.1.0
GzipSeekable
Random-access (seekable) reading of gzip (DEFLATE) streams in .NET.
gzip streams are normally forward-only: reading byte N means decompressing everything before it. GzipSeekable gives you a standard seekable Stream over gzip data via a zran-style checkpoint index: one sequential decode builds it (persist it; later opens are instant), then any read decodes only from the nearest checkpoint — by default at most ~4 MiB away.
Everything is managed code (a vendored DEFLATE inflater from SharpZipLib with small, guarded resume additions) — no native binaries. Multi-member (concatenated) gzip is handled natively. Targets netstandard2.0 and net8.0.
Quick start
using GzipSeekable;
// Build a checkpoint index once, then seek freely. The build is one sequential decode
// (streaming and resumable if interrupted); the index persists to disk, so later opens
// are instant.
using var compressed = File.OpenRead(@"C:\images\disk.img.gz");
using var index = GzipIndex.LoadOrBuild(compressed, @"C:\images\disk.img.gzsi");
using var stream = new GzipIndexedStream(compressed, index);
stream.Position = 123_456_789; // decodes from the nearest checkpoint, not from byte 0
var buffer = new byte[4096];
var read = stream.Read(buffer, 0, buffer.Length);
How it works
A DEFLATE checkpoint needs only two things: the last 32 KiB of decompressed history (the sliding window) and the sub-byte bit position where the next deflate block starts — this is exactly zlib's zran.c model. GzipIndex.LoadOrBuild decodes the stream once and drops a checkpoint at the first deflate block boundary past every span (GzipIndexOptions.TargetSpanBytes, default 4 MiB), storing each window DEFLATE-compressed and loading it lazily — only when a read actually resumes there. Runs of a constant byte are recorded as fill spans and served without touching the decoder at all. Each gzip member's CRC32 and length are verified during the build (GzipIndexOptions.VerifyMemberCrc), a sample of checkpoints is byte-verified with a shadow decoder (GzipIndexOptions.VerifiedSampleSpans), sealed records stream to <index>.wip as the build progresses (flat memory; an interrupted build resumes from its last sealed checkpoint), and the file is finalised atomically. The persisted format is "GZSKIDX1"; the index is fingerprinted against the compressed stream and rebuilt automatically if it doesn't match.
Multi-member gzip: every member start becomes a (stateless) checkpoint, and serving continues across member boundaries transparently.
Note for sequential consumers: each Read resumes from a checkpoint, so naive byte-at-a-time forward reading re-decodes spans repeatedly. Read span-sized chunks (see GzipIndexedStream.GetRecommendation) or put a cache in front.
License
MIT. Includes a vendored copy of the DEFLATE inflater from SharpZipLib (MIT). See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
- System.Memory (>= 4.6.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 101 | 7/20/2026 |
Initial release: random access into gzip (DEFLATE) streams via a verified zran-style checkpoint index - build once (streaming, resumable), then seek freely. Multi-member gzip supported natively. Self-contained managed code; no native binaries.