change docs

This commit is contained in:
Adam Hathcock
2026-02-17 13:01:23 +00:00
parent d362a0ff4f
commit ca84e7ed29
3 changed files with 100 additions and 13 deletions

View File

@@ -67,6 +67,19 @@ var options2 = new WriterOptions(CompressionType.Deflate)
};
```
### Format-specific Openables (.NET 8+)
```csharp
// Reader static openables return format-specific interfaces
using var zipReader = ZipReader.OpenReader(stream); // IZipReader
using var sevenZipReader = SevenZipReader.OpenReader(stream); // ISevenZipReader
// Writer static openables return format-specific interfaces
using var zipWriter = ZipWriter.OpenWriter(output, new ZipWriterOptions(CompressionType.Deflate)); // IZipWriter
using var tarWriter = TarWriter.OpenWriter(output, new TarWriterOptions(CompressionType.None)); // ITarWriter
using var gzipWriter = GZipWriter.OpenWriter(output, new GZipWriterOptions()); // IGZipWriter
```
---
## Archive API Methods

View File

@@ -22,12 +22,12 @@
| Tar.LZip | LZMA | Both | TarArchive | TarReader | TarWriter (3) |
| Tar.XZ | LZMA2 | Decompress | TarArchive | TarReader | TarWriter (3) |
| GZip (single file) | DEFLATE | Both | GZipArchive | GZipReader | GZipWriter |
| 7Zip (4) | LZMA, LZMA2, BZip2, PPMd, BCJ, BCJ2, Deflate | Decompress | SevenZipArchive | N/A | N/A |
| 7Zip (4) | LZMA, LZMA2, BZip2, PPMd, BCJ, BCJ2, Deflate | Decompress | SevenZipArchive | SevenZipReader | N/A |
1. SOLID Rars are only supported in the RarReader API.
2. Zip format supports pkware and WinzipAES encryption. However, encrypted LZMA is not supported. Zip64 reading/writing is supported but only with seekable streams as the Zip spec doesn't support Zip64 data in post data descriptors. Deflate64 is only supported for reading. See [Zip Format Notes](#zip-format-notes) for details on multi-volume archives and streaming behavior.
3. The Tar format requires a file size in the header. If no size is specified to the TarWriter and the stream is not seekable, then an exception will be thrown.
4. The 7Zip format doesn't allow for reading as a forward-only stream so 7Zip is only supported through the Archive API. See [7Zip Format Notes](#7zip-format-notes) for details on async extraction behavior.
4. 7Zip supports sequential reader extraction through `SevenZipReader`/`ReaderFactory`, but does not support random per-entry extraction via `IExtractableArchive` (entries must be processed sequentially). See [7Zip Format Notes](#7zip-format-notes).
5. LZip has no support for extra data like the file name or timestamp. There is a default filename used when looking at the entry Key on the archive.
### Zip Format Notes
@@ -37,15 +37,12 @@
### 7Zip Format Notes
- **Async Extraction Performance**: When using async extraction methods (e.g., `ExtractAllEntries()` with `MoveToNextEntryAsync()`), each file creates its own decompression stream to avoid state corruption in the LZMA decoder. This is less efficient than synchronous extraction, which can reuse a single decompression stream for multiple files in the same folder.
**Performance Impact**: For archives with many small files in the same compression folder, async extraction will be slower than synchronous extraction because it must:
1. Create a new LZMA decoder for each file
2. Skip through the decompressed data to reach each file's starting position
**Recommendation**: For best performance with 7Zip archives, use synchronous extraction methods (`MoveToNextEntry()` and `WriteEntryToDirectory()`) when possible. Use async methods only when you need to avoid blocking the thread (e.g., in UI applications or async-only contexts).
**Technical Details**: 7Zip archives group files into "folders" (compression units), where all files in a folder share one continuous LZMA-compressed stream. The LZMA decoder maintains internal state (dictionary window, decoder positions) that assumes sequential, non-interruptible processing. Async operations can yield control during awaits, which would corrupt this shared state. To avoid this, async extraction creates a fresh decoder stream for each file.
- 7Zip supports sequential extraction through:
- `SevenZipArchive.ExtractAllEntries()` / `ExtractAllEntriesAsync()`
- `SevenZipReader.OpenReader(...)` / `OpenAsyncReader(...)`
- `ReaderFactory.OpenReader(...)` / `OpenAsyncReader(...)` (auto-detect)
- 7Zip entries are organized into compression folders and should be processed in archive order for best performance.
- 7Zip still does **not** implement `IExtractableArchive`; individual random-access `OpenEntryStream` extraction from archive entries is not supported.
## Compression Streams

View File

@@ -288,6 +288,33 @@ classDiagram
IFactory <|-- IWriterFactory
```
### Static Openable Interfaces (.NET 8+)
```mermaid
classDiagram
direction TB
class IReaderOpenable~TReader,TAsyncReader~ {
<<interface>>
+OpenReader(filePath, options) TReader
+OpenReader(fileInfo, options) TReader
+OpenReader(stream, options) TReader
+OpenAsyncReader(path, options, ct) ValueTask~TAsyncReader~
+OpenAsyncReader(fileInfo, options, ct) ValueTask~TAsyncReader~
+OpenAsyncReader(stream, options, ct) ValueTask~TAsyncReader~
}
class IWriterOpenable~TWriter,TAsyncWriter,TOptions~ {
<<interface>>
+OpenWriter(filePath, options) TWriter
+OpenWriter(fileInfo, options) TWriter
+OpenWriter(stream, options) TWriter
+OpenAsyncWriter(filePath, options) TAsyncWriter
+OpenAsyncWriter(fileInfo, options) TAsyncWriter
+OpenAsyncWriter(stream, options) TAsyncWriter
}
```
---
## Format-Specific Interfaces
@@ -396,6 +423,12 @@ classDiagram
class ILzwReader {
<<interface>>
}
class ISevenZipReader {
<<interface>>
}
class ISevenZipAsyncReader {
<<interface>>
}
IReader <|-- IZipReader
IAsyncReader <|-- IZipAsyncReader
@@ -407,6 +440,48 @@ classDiagram
IReader <|-- IArcReader
IReader <|-- IArjReader
IReader <|-- ILzwReader
IReader <|-- ISevenZipReader
IAsyncReader <|-- ISevenZipAsyncReader
```
### Writer Formats
```mermaid
classDiagram
direction LR
class IWriter {
<<interface>>
}
class IAsyncWriter {
<<interface>>
}
class IZipWriter {
<<interface>>
}
class IZipAsyncWriter {
<<interface>>
}
class ITarWriter {
<<interface>>
}
class ITarAsyncWriter {
<<interface>>
}
class IGZipWriter {
<<interface>>
}
class IGZipAsyncWriter {
<<interface>>
}
IWriter <|-- IZipWriter
IAsyncWriter <|-- IZipAsyncWriter
IWriter <|-- ITarWriter
IAsyncWriter <|-- ITarAsyncWriter
IWriter <|-- IGZipWriter
IAsyncWriter <|-- IGZipAsyncWriter
```
---
@@ -552,8 +627,10 @@ await writer.WriteAsync("file.txt", contentStream, DateTime.Now);
2. **IExtractableArchive**: Separates archives that support random entry extraction from those that don't (7Zip requires sequential processing).
3. **Marker Interfaces**: Format-specific interfaces (`IZipArchive`, `ITarReader`) are markers that allow type-safe casting when format-specific features are needed.
3. **Marker Interfaces**: Format-specific interfaces (`IZipArchive`, `ITarReader`, `IZipWriter`) are markers that allow type-safe casting when format-specific features are needed.
4. **Factory Pattern**: All instances are created through factories (`ArchiveFactory`, `ReaderFactory`, `WriterFactory`) which handle format detection and instantiation.
5. **Entry Hierarchy**: `IEntry``IArchiveEntry``IExtractableArchiveEntry` provides progressive capabilities.
5. **Static Openable Pattern (.NET 8+)**: Reader/Writer implementations can implement `IReaderOpenable<...>` and `IWriterOpenable<...>` to expose strongly-typed static `Open*` APIs.
6. **Entry Hierarchy**: `IEntry``IArchiveEntry``IExtractableArchiveEntry` provides progressive capabilities.