mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-04 13:34:59 +00:00
Compare commits
24 Commits
adam/memor
...
copilot/su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a6e5232ae | ||
|
|
3e23a6e5a6 | ||
|
|
e0a43e9727 | ||
|
|
f5d83c0e33 | ||
|
|
d2cb792d91 | ||
|
|
52fef492a5 | ||
|
|
a5300f3383 | ||
|
|
cab3e7d498 | ||
|
|
405dbb30cd | ||
|
|
3e219fa9ec | ||
|
|
ec310c87de | ||
|
|
c55a383112 | ||
|
|
227fec66ad | ||
|
|
38eec23e07 | ||
|
|
437271c6a2 | ||
|
|
81a2060c75 | ||
|
|
5e90cfd6c5 | ||
|
|
b41296194f | ||
|
|
bf7416753a | ||
|
|
7fbd751d27 | ||
|
|
85b28dfe68 | ||
|
|
779fba5deb | ||
|
|
2756b1f6f8 | ||
|
|
7b76858ae1 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -20,7 +20,3 @@ artifacts/
|
||||
|
||||
.DS_Store
|
||||
*.snupkg
|
||||
|
||||
# BenchmarkDotNet artifacts
|
||||
BenchmarkDotNet.Artifacts/
|
||||
**/BenchmarkDotNet.Artifacts/
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
|
||||
<PackageVersion Include="Bullseye" Version="6.1.0" />
|
||||
<PackageVersion Include="AwesomeAssertions" Version="9.3.0" />
|
||||
<PackageVersion Include="Glob" Version="1.1.9" />
|
||||
|
||||
80
docs/API.md
80
docs/API.md
@@ -8,17 +8,17 @@ Quick reference for commonly used SharpCompress APIs.
|
||||
|
||||
```csharp
|
||||
// Auto-detect format
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
// Works with Zip, Tar, GZip, Rar, 7Zip, etc.
|
||||
}
|
||||
|
||||
// Specific format - Archive API
|
||||
using (var archive = ZipArchive.Open("file.zip"))
|
||||
using (var archive = TarArchive.Open("file.tar"))
|
||||
using (var archive = RarArchive.Open("file.rar"))
|
||||
using (var archive = SevenZipArchive.Open("file.7z"))
|
||||
using (var archive = GZipArchive.Open("file.gz"))
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip"))
|
||||
using (var archive = TarArchive.OpenArchive("file.tar"))
|
||||
using (var archive = RarArchive.OpenArchive("file.rar"))
|
||||
using (var archive = SevenZipArchive.OpenArchive("file.7z"))
|
||||
using (var archive = GZipArchive.OpenArchive("file.gz"))
|
||||
|
||||
// With options
|
||||
var options = new ReaderOptions
|
||||
@@ -27,30 +27,30 @@ var options = new ReaderOptions
|
||||
LeaveStreamOpen = true,
|
||||
ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) }
|
||||
};
|
||||
using (var archive = ZipArchive.Open("encrypted.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("encrypted.zip", options))
|
||||
```
|
||||
|
||||
### Creating Archives
|
||||
|
||||
```csharp
|
||||
// Writer Factory
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
{
|
||||
// Write entries
|
||||
}
|
||||
|
||||
// Specific writer
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = TarArchive.Create())
|
||||
using (var archive = GZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
using (var archive = TarArchive.CreateArchive())
|
||||
using (var archive = GZipArchive.CreateArchive())
|
||||
|
||||
// With options
|
||||
var options = new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
var options = new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
CompressionLevel = 9,
|
||||
LeaveStreamOpen = false
|
||||
};
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.SaveTo("output.zip", options);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ using (var archive = ZipArchive.Create())
|
||||
### Reading/Extracting
|
||||
|
||||
```csharp
|
||||
using (var archive = ZipArchive.Open("file.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip"))
|
||||
{
|
||||
// Get all entries
|
||||
IEnumerable<IArchiveEntry> entries = archive.Entries;
|
||||
@@ -91,7 +91,7 @@ using (var archive = ZipArchive.Open("file.zip"))
|
||||
}
|
||||
|
||||
// Async extraction (requires IAsyncArchive)
|
||||
using (var asyncArchive = await ZipArchive.OpenAsync("file.zip"))
|
||||
using (var asyncArchive = await ZipArchive.OpenAsyncArchive("file.zip"))
|
||||
{
|
||||
await asyncArchive.WriteToDirectoryAsync(
|
||||
@"C:\output",
|
||||
@@ -122,7 +122,7 @@ foreach (var entry in archive.Entries)
|
||||
### Creating Archives
|
||||
|
||||
```csharp
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
// Add file
|
||||
archive.AddEntry("file.txt", @"C:\source\file.txt");
|
||||
@@ -151,7 +151,7 @@ using (var archive = ZipArchive.Create())
|
||||
|
||||
```csharp
|
||||
using (var stream = File.OpenRead("file.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -172,9 +172,9 @@ using (var reader = ReaderFactory.Open(stream))
|
||||
}
|
||||
}
|
||||
|
||||
// Async variants (use OpenAsync to get IAsyncReader)
|
||||
// Async variants (use OpenAsyncReader to get IAsyncReader)
|
||||
using (var stream = File.OpenRead("file.zip"))
|
||||
using (var reader = await ReaderFactory.OpenAsync(stream))
|
||||
using (var reader = await ReaderFactory.OpenAsyncReader(stream))
|
||||
{
|
||||
while (await reader.MoveToNextEntryAsync())
|
||||
{
|
||||
@@ -201,7 +201,7 @@ using (var reader = await ReaderFactory.OpenAsync(stream))
|
||||
|
||||
```csharp
|
||||
using (var stream = File.Create("output.zip"))
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
{
|
||||
// Write single file
|
||||
using (var fileStream = File.OpenRead("source.txt"))
|
||||
@@ -239,7 +239,7 @@ var options = new ReaderOptions
|
||||
Default = Encoding.GetEncoding(932)
|
||||
}
|
||||
};
|
||||
using (var archive = ZipArchive.Open("file.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip", options))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
@@ -290,8 +290,8 @@ ArchiveType.Ace
|
||||
|
||||
// For Tar archives with compression
|
||||
// Use WriterFactory to create compressed tar archives
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Tar, CompressionType.GZip)) // Tar.GZip
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Tar, CompressionType.BZip2)) // Tar.BZip2
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Tar, CompressionType.GZip)) // Tar.GZip
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Tar, CompressionType.BZip2)) // Tar.BZip2
|
||||
```
|
||||
|
||||
### Archive Types
|
||||
@@ -349,7 +349,7 @@ var progress = new Progress<ProgressReport>(report =>
|
||||
});
|
||||
|
||||
var options = new ReaderOptions { Progress = progress };
|
||||
using (var archive = ZipArchive.Open("archive.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip", options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -363,7 +363,7 @@ cts.CancelAfter(TimeSpan.FromMinutes(5));
|
||||
|
||||
try
|
||||
{
|
||||
using (var archive = await ZipArchive.OpenAsync("archive.zip"))
|
||||
using (var archive = await ZipArchive.OpenAsyncArchive("archive.zip"))
|
||||
{
|
||||
await archive.WriteToDirectoryAsync(
|
||||
@"C:\output",
|
||||
@@ -381,23 +381,23 @@ catch (OperationCanceledException)
|
||||
### Create with Custom Compression
|
||||
|
||||
```csharp
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory(@"D:\source");
|
||||
|
||||
// Fastest
|
||||
archive.SaveTo("fast.zip", new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
CompressionLevel = 1
|
||||
archive.SaveTo("fast.zip", new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
CompressionLevel = 1
|
||||
});
|
||||
|
||||
// Balanced (default)
|
||||
archive.SaveTo("normal.zip", CompressionType.Deflate);
|
||||
|
||||
// Best compression
|
||||
archive.SaveTo("best.zip", new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
CompressionLevel = 9
|
||||
archive.SaveTo("best.zip", new WriterOptions(CompressionType.Deflate)
|
||||
{
|
||||
CompressionLevel = 9
|
||||
});
|
||||
}
|
||||
```
|
||||
@@ -406,7 +406,7 @@ using (var archive = ZipArchive.Create())
|
||||
|
||||
```csharp
|
||||
using (var outputStream = new MemoryStream())
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
// Add content from memory
|
||||
using (var contentStream = new MemoryStream(Encoding.UTF8.GetBytes("Hello")))
|
||||
@@ -425,7 +425,7 @@ using (var archive = ZipArchive.Create())
|
||||
### Extract Specific Files
|
||||
|
||||
```csharp
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
var filesToExtract = new[] { "file1.txt", "file2.txt" };
|
||||
|
||||
@@ -439,7 +439,7 @@ using (var archive = ZipArchive.Open("archive.zip"))
|
||||
### List Archive Contents
|
||||
|
||||
```csharp
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -459,7 +459,7 @@ using (var archive = ZipArchive.Open("archive.zip"))
|
||||
|
||||
```csharp
|
||||
var stream = File.OpenRead("archive.zip");
|
||||
var archive = ZipArchive.Open(stream);
|
||||
var archive = ZipArchive.OpenArchive(stream);
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
// stream not disposed - leaked resource
|
||||
```
|
||||
@@ -468,7 +468,7 @@ archive.WriteToDirectory(@"C:\output");
|
||||
|
||||
```csharp
|
||||
using (var stream = File.OpenRead("archive.zip"))
|
||||
using (var archive = ZipArchive.Open(stream))
|
||||
using (var archive = ZipArchive.OpenArchive(stream))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -479,7 +479,7 @@ using (var archive = ZipArchive.Open(stream))
|
||||
|
||||
```csharp
|
||||
// Loading entire archive then iterating
|
||||
using (var archive = ZipArchive.Open("large.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("large.zip"))
|
||||
{
|
||||
var entries = archive.Entries.ToList(); // Loads all in memory
|
||||
foreach (var e in entries)
|
||||
@@ -494,7 +494,7 @@ using (var archive = ZipArchive.Open("large.zip"))
|
||||
```csharp
|
||||
// Streaming iteration
|
||||
using (var stream = File.OpenRead("large.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
|
||||
@@ -76,7 +76,7 @@ Factory classes for auto-detecting archive format and creating appropriate reade
|
||||
- Format-specific: `ZipFactory.cs`, `TarFactory.cs`, `RarFactory.cs`, etc.
|
||||
|
||||
**How It Works:**
|
||||
1. `ReaderFactory.Open(stream)` probes stream signatures
|
||||
1. `ReaderFactory.OpenReader(stream)` probes stream signatures
|
||||
2. Identifies format by magic bytes
|
||||
3. Creates appropriate reader instance
|
||||
4. Returns generic `IReader` interface
|
||||
@@ -142,7 +142,7 @@ Stream wrappers and utilities.
|
||||
**Example:**
|
||||
```csharp
|
||||
// User calls factory
|
||||
using (var reader = ReaderFactory.Open(stream)) // Returns IReader
|
||||
using (var reader = ReaderFactory.OpenReader(stream)) // Returns IReader
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -175,7 +175,7 @@ CompressionType.LZMA // LZMA
|
||||
CompressionType.PPMd // PPMd
|
||||
|
||||
// Writer uses strategy pattern
|
||||
var archive = ZipArchive.Create();
|
||||
var archive = ZipArchive.CreateArchive();
|
||||
archive.SaveTo("output.zip", CompressionType.Deflate); // Use Deflate
|
||||
archive.SaveTo("output.bz2", CompressionType.BZip2); // Use BZip2
|
||||
```
|
||||
@@ -248,7 +248,7 @@ foreach (var entry in entries)
|
||||
}
|
||||
|
||||
// Reader API - provides iterator
|
||||
IReader reader = ReaderFactory.Open(stream);
|
||||
IReader reader = ReaderFactory.OpenReader(stream);
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
// Forward-only iteration - one entry at a time
|
||||
@@ -381,7 +381,7 @@ public class NewFormatArchive : AbstractArchive
|
||||
private NewFormatHeader _header;
|
||||
private List<NewFormatEntry> _entries;
|
||||
|
||||
public static NewFormatArchive Open(Stream stream)
|
||||
public static NewFormatArchive OpenArchive(Stream stream)
|
||||
{
|
||||
var archive = new NewFormatArchive();
|
||||
archive._header = NewFormatHeader.Read(stream);
|
||||
@@ -442,8 +442,8 @@ public class NewFormatFactory : Factory, IArchiveFactory, IReaderFactory
|
||||
|
||||
public static NewFormatFactory Instance { get; } = new();
|
||||
|
||||
public IArchive CreateArchive(Stream stream)
|
||||
=> NewFormatArchive.Open(stream);
|
||||
public IArchive CreateArchive(Stream stream)
|
||||
=> NewFormatArchive.OpenArchive(stream);
|
||||
|
||||
public IReader CreateReader(Stream stream, ReaderOptions options)
|
||||
=> new NewFormatReader(stream) { Options = options };
|
||||
@@ -481,7 +481,7 @@ public class NewFormatTests : TestBase
|
||||
public void NewFormat_Extracts_Successfully()
|
||||
{
|
||||
var archivePath = Path.Combine(TEST_ARCHIVES_PATH, "archive.newformat");
|
||||
using (var archive = NewFormatArchive.Open(archivePath))
|
||||
using (var archive = NewFormatArchive.OpenArchive(archivePath))
|
||||
{
|
||||
archive.WriteToDirectory(SCRATCH_FILES_PATH);
|
||||
// Assert extraction
|
||||
@@ -561,7 +561,7 @@ public class CustomStream : Stream
|
||||
```csharp
|
||||
// Correct: Nested using blocks
|
||||
using (var fileStream = File.OpenRead("archive.zip"))
|
||||
using (var archive = ZipArchive.Open(fileStream))
|
||||
using (var archive = ZipArchive.OpenArchive(fileStream))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -570,7 +570,7 @@ using (var archive = ZipArchive.Open(fileStream))
|
||||
// Correct: Using with options
|
||||
var options = new ReaderOptions { LeaveStreamOpen = true };
|
||||
var stream = File.OpenRead("archive.zip");
|
||||
using (var archive = ZipArchive.Open(stream, options))
|
||||
using (var archive = ZipArchive.OpenArchive(stream, options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -641,7 +641,7 @@ public void Archive_Extraction_Works()
|
||||
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "test.zip");
|
||||
|
||||
// Act
|
||||
using (var archive = ZipArchive.Open(testArchive))
|
||||
using (var archive = ZipArchive.OpenArchive(testArchive))
|
||||
{
|
||||
archive.WriteToDirectory(SCRATCH_FILES_PATH);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("japanese.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("japanese.zip", options))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -51,7 +51,7 @@ var options = new ReaderOptions
|
||||
{
|
||||
ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) }
|
||||
};
|
||||
using (var archive = ZipArchive.Open("file.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip", options))
|
||||
{
|
||||
// Use archive with correct encoding
|
||||
}
|
||||
@@ -64,7 +64,7 @@ var options = new ReaderOptions
|
||||
ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) }
|
||||
};
|
||||
using (var stream = File.OpenRead("file.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream, options))
|
||||
using (var reader = ReaderFactory.OpenReader(stream, options))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -89,7 +89,7 @@ var options = new ReaderOptions
|
||||
Default = Encoding.GetEncoding(932)
|
||||
}
|
||||
};
|
||||
using (var archive = ZipArchive.Open("japanese.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("japanese.zip", options))
|
||||
{
|
||||
// Correctly decodes Japanese filenames
|
||||
}
|
||||
@@ -266,7 +266,7 @@ SharpCompress attempts to auto-detect encoding, but this isn't always reliable:
|
||||
|
||||
```csharp
|
||||
// Auto-detection (default)
|
||||
using (var archive = ZipArchive.Open("file.zip")) // Uses UTF8 by default
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip")) // Uses UTF8 by default
|
||||
{
|
||||
// May show corrupted characters if archive uses different encoding
|
||||
}
|
||||
@@ -276,7 +276,7 @@ var options = new ReaderOptions
|
||||
{
|
||||
ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) }
|
||||
};
|
||||
using (var archive = ZipArchive.Open("file.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("file.zip", options))
|
||||
{
|
||||
// Correct characters displayed
|
||||
}
|
||||
@@ -324,7 +324,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("mixed.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("mixed.zip", options))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -388,7 +388,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("japanese_files.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("japanese_files.zip", options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output", new ExtractionOptions
|
||||
{
|
||||
@@ -410,7 +410,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("french_files.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("french_files.zip", options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -428,7 +428,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("chinese_files.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("chinese_files.zip", options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -445,7 +445,7 @@ var options = new ReaderOptions
|
||||
}
|
||||
};
|
||||
|
||||
using (var archive = ZipArchive.Open("russian_files.zip", options))
|
||||
using (var archive = ZipArchive.OpenArchive("russian_files.zip", options))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -463,7 +463,7 @@ var options = new ReaderOptions
|
||||
};
|
||||
|
||||
using (var stream = File.OpenRead("japanese.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream, options))
|
||||
using (var reader = ReaderFactory.OpenReader(stream, options))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -484,7 +484,7 @@ When creating archives, SharpCompress uses UTF8 by default (recommended):
|
||||
|
||||
```csharp
|
||||
// Create with UTF8 (default, recommended)
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory(@"D:\my_files");
|
||||
archive.SaveTo("output.zip", CompressionType.Deflate);
|
||||
|
||||
@@ -24,7 +24,7 @@ Choose the right API based on your use case:
|
||||
// - You need random access to entries
|
||||
// - Stream is seekable (file, MemoryStream)
|
||||
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
// Random access - all entries available
|
||||
var specific = archive.Entries.FirstOrDefault(e => e.Key == "file.txt");
|
||||
@@ -51,7 +51,7 @@ using (var archive = ZipArchive.Open("archive.zip"))
|
||||
// - Forward-only processing is acceptable
|
||||
|
||||
using (var stream = File.OpenRead("large.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -129,7 +129,7 @@ For processing archives from downloads or pipes:
|
||||
```csharp
|
||||
// Download stream (non-seekable)
|
||||
using (var httpStream = await httpClient.GetStreamAsync(url))
|
||||
using (var reader = ReaderFactory.Open(httpStream))
|
||||
using (var reader = ReaderFactory.OpenReader(httpStream))
|
||||
{
|
||||
// Process entries as they arrive
|
||||
while (reader.MoveToNextEntry())
|
||||
@@ -159,14 +159,14 @@ Choose based on your constraints:
|
||||
```csharp
|
||||
// Download then extract (requires disk space)
|
||||
var archivePath = await DownloadFile(url, @"C:\temp\archive.zip");
|
||||
using (var archive = ZipArchive.Open(archivePath))
|
||||
using (var archive = ZipArchive.OpenArchive(archivePath))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
|
||||
// Stream during download (on-the-fly extraction)
|
||||
using (var httpStream = await httpClient.GetStreamAsync(url))
|
||||
using (var reader = ReaderFactory.Open(httpStream))
|
||||
using (var reader = ReaderFactory.OpenReader(httpStream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -198,7 +198,7 @@ Extracting File3 requires decompressing File1 and File2 first.
|
||||
|
||||
**Random Extraction (Slow):**
|
||||
```csharp
|
||||
using (var archive = RarArchive.Open("solid.rar"))
|
||||
using (var archive = RarArchive.OpenArchive("solid.rar"))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
@@ -210,7 +210,7 @@ using (var archive = RarArchive.Open("solid.rar"))
|
||||
|
||||
**Sequential Extraction (Fast):**
|
||||
```csharp
|
||||
using (var archive = RarArchive.Open("solid.rar"))
|
||||
using (var archive = RarArchive.OpenArchive("solid.rar"))
|
||||
{
|
||||
// Method 1: Use WriteToDirectory (recommended)
|
||||
archive.WriteToDirectory(@"C:\output", new ExtractionOptions
|
||||
@@ -256,7 +256,7 @@ using (var archive = RarArchive.Open("solid.rar"))
|
||||
// Level 9 = Slowest, best compression
|
||||
|
||||
// Write with different compression levels
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory(@"D:\data");
|
||||
|
||||
@@ -293,7 +293,7 @@ using (var archive = ZipArchive.Create())
|
||||
// Smaller block size = lower memory, faster
|
||||
// Larger block size = better compression, slower
|
||||
|
||||
using (var archive = TarArchive.Create())
|
||||
using (var archive = TarArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory(@"D:\data");
|
||||
|
||||
@@ -313,7 +313,7 @@ LZMA compression is very powerful but memory-intensive:
|
||||
// - Better compression: larger dictionary
|
||||
|
||||
// Preset via CompressionType
|
||||
using (var archive = TarArchive.Create())
|
||||
using (var archive = TarArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory(@"D:\data");
|
||||
archive.SaveTo("archive.tar.xz", CompressionType.LZMA); // Default settings
|
||||
@@ -333,7 +333,7 @@ Async is beneficial when:
|
||||
|
||||
```csharp
|
||||
// Async extraction (non-blocking)
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
await archive.WriteToDirectoryAsync(
|
||||
@"C:\output",
|
||||
@@ -353,7 +353,7 @@ Async doesn't improve performance for:
|
||||
|
||||
```csharp
|
||||
// Sync extraction (simpler, same performance on fast I/O)
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
archive.WriteToDirectory(
|
||||
@"C:\output",
|
||||
@@ -373,7 +373,7 @@ cts.CancelAfter(TimeSpan.FromMinutes(5));
|
||||
|
||||
try
|
||||
{
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
await archive.WriteToDirectoryAsync(
|
||||
@"C:\output",
|
||||
@@ -408,14 +408,14 @@ catch (OperationCanceledException)
|
||||
// ✗ Slow - opens each archive separately
|
||||
foreach (var file in files)
|
||||
{
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
}
|
||||
|
||||
// ✓ Better - process multiple entries at once
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
@@ -425,7 +425,7 @@ using (var archive = ZipArchive.Open("archive.zip"))
|
||||
|
||||
```csharp
|
||||
var sw = Stopwatch.StartNew();
|
||||
using (var archive = ZipArchive.Open("large.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("large.zip"))
|
||||
{
|
||||
archive.WriteToDirectory(@"C:\output");
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ Also, look over the tests for more thorough [examples](https://github.com/adamha
|
||||
|
||||
### Create Zip Archive from multiple files
|
||||
```C#
|
||||
using(var archive = ZipArchive.Create())
|
||||
using(var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddEntry("file01.txt", "C:\\file01.txt");
|
||||
archive.AddEntry("file02.txt", "C:\\file02.txt");
|
||||
@@ -61,7 +61,7 @@ using(var archive = ZipArchive.Create())
|
||||
### Create Zip Archive from all files in a directory to a file
|
||||
|
||||
```C#
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory("D:\\temp");
|
||||
archive.SaveTo("C:\\temp.zip", CompressionType.Deflate);
|
||||
@@ -72,7 +72,7 @@ using (var archive = ZipArchive.Create())
|
||||
|
||||
```C#
|
||||
var memoryStream = new MemoryStream();
|
||||
using (var archive = ZipArchive.Create())
|
||||
using (var archive = ZipArchive.CreateArchive())
|
||||
{
|
||||
archive.AddAllFromDirectory("D:\\temp");
|
||||
archive.SaveTo(memoryStream, new WriterOptions(CompressionType.Deflate)
|
||||
@@ -90,7 +90,7 @@ Note: Extracting a solid rar or 7z file needs to be done in sequential order to
|
||||
`ExtractAllEntries` is primarily intended for solid archives (like solid Rar) or 7Zip archives, where sequential extraction provides the best performance. For general/simple extraction with any supported archive type, use `archive.WriteToDirectory()` instead.
|
||||
|
||||
```C#
|
||||
using (var archive = RarArchive.Open("Test.rar"))
|
||||
using (var archive = RarArchive.OpenArchive("Test.rar"))
|
||||
{
|
||||
// Simple extraction with RarArchive; this WriteToDirectory pattern works for all archive types
|
||||
archive.WriteToDirectory(@"D:\temp", new ExtractionOptions()
|
||||
@@ -104,7 +104,7 @@ using (var archive = RarArchive.Open("Test.rar"))
|
||||
### Iterate over all files from a Rar file using RarArchive
|
||||
|
||||
```C#
|
||||
using (var archive = RarArchive.Open("Test.rar"))
|
||||
using (var archive = RarArchive.OpenArchive("Test.rar"))
|
||||
{
|
||||
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
|
||||
{
|
||||
@@ -126,7 +126,7 @@ var progress = new Progress<ProgressReport>(report =>
|
||||
Console.WriteLine($"Extracting {report.EntryPath}: {report.PercentComplete}%");
|
||||
});
|
||||
|
||||
using (var archive = RarArchive.Open("archive.rar", new ReaderOptions { Progress = progress })) // Must be solid Rar or 7Zip
|
||||
using (var archive = RarArchive.OpenArchive("archive.rar", new ReaderOptions { Progress = progress })) // Must be solid Rar or 7Zip
|
||||
{
|
||||
archive.WriteToDirectory(@"D:\output", new ExtractionOptions()
|
||||
{
|
||||
@@ -140,7 +140,7 @@ using (var archive = RarArchive.Open("archive.rar", new ReaderOptions { Progress
|
||||
|
||||
```C#
|
||||
using (Stream stream = File.OpenRead("Tar.tar.bz2"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -161,7 +161,7 @@ using (var reader = ReaderFactory.Open(stream))
|
||||
|
||||
```C#
|
||||
using (Stream stream = File.OpenRead("Tar.tar.bz2"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -180,7 +180,7 @@ using (var reader = ReaderFactory.Open(stream))
|
||||
|
||||
```C#
|
||||
using (Stream stream = File.OpenWrite("C:\\temp.tgz"))
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Tar, new WriterOptions(CompressionType.GZip)
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Tar, new WriterOptions(CompressionType.GZip)
|
||||
{
|
||||
LeaveOpenStream = true
|
||||
}))
|
||||
@@ -199,7 +199,7 @@ opts.ArchiveEncoding.CustomDecoder = (data, x, y) =>
|
||||
{
|
||||
return encoding.GetString(data);
|
||||
};
|
||||
var tr = SharpCompress.Archives.Zip.ZipArchive.Open("test.zip", opts);
|
||||
var tr = SharpCompress.Archives.Zip.ZipArchive.OpenArchive("test.zip", opts);
|
||||
foreach(var entry in tr.Entries)
|
||||
{
|
||||
Console.WriteLine($"{entry.Key}");
|
||||
@@ -213,7 +213,7 @@ foreach(var entry in tr.Entries)
|
||||
**Extract single entry asynchronously:**
|
||||
```C#
|
||||
using (Stream stream = File.OpenRead("archive.zip"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -234,7 +234,7 @@ using (var reader = ReaderFactory.Open(stream))
|
||||
**Extract all entries asynchronously:**
|
||||
```C#
|
||||
using (Stream stream = File.OpenRead("archive.tar.gz"))
|
||||
using (var reader = ReaderFactory.Open(stream))
|
||||
using (var reader = ReaderFactory.OpenReader(stream))
|
||||
{
|
||||
await reader.WriteAllToDirectoryAsync(
|
||||
@"D:\temp",
|
||||
@@ -250,7 +250,7 @@ using (var reader = ReaderFactory.Open(stream))
|
||||
|
||||
**Open and process entry stream asynchronously:**
|
||||
```C#
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
foreach (var entry in archive.Entries.Where(e => !e.IsDirectory))
|
||||
{
|
||||
@@ -268,7 +268,7 @@ using (var archive = ZipArchive.Open("archive.zip"))
|
||||
**Write single file asynchronously:**
|
||||
```C#
|
||||
using (Stream archiveStream = File.OpenWrite("output.zip"))
|
||||
using (var writer = WriterFactory.Open(archiveStream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
using (var writer = WriterFactory.OpenWriter(archiveStream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
{
|
||||
using (Stream fileStream = File.OpenRead("input.txt"))
|
||||
{
|
||||
@@ -280,7 +280,7 @@ using (var writer = WriterFactory.Open(archiveStream, ArchiveType.Zip, Compressi
|
||||
**Write entire directory asynchronously:**
|
||||
```C#
|
||||
using (Stream stream = File.OpenWrite("backup.tar.gz"))
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Tar, new WriterOptions(CompressionType.GZip)))
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Tar, new WriterOptions(CompressionType.GZip)))
|
||||
{
|
||||
await writer.WriteAllAsync(
|
||||
@"D:\files",
|
||||
@@ -299,7 +299,7 @@ var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(TimeSpan.FromMinutes(5));
|
||||
|
||||
using (Stream stream = File.OpenWrite("archive.zip"))
|
||||
using (var writer = WriterFactory.Open(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Zip, CompressionType.Deflate))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -316,7 +316,7 @@ using (var writer = WriterFactory.Open(stream, ArchiveType.Zip, CompressionType.
|
||||
|
||||
**Extract from archive asynchronously:**
|
||||
```C#
|
||||
using (var archive = ZipArchive.Open("archive.zip"))
|
||||
using (var archive = ZipArchive.OpenArchive("archive.zip"))
|
||||
{
|
||||
// Simple async extraction - works for all archive types
|
||||
await archive.WriteToDirectoryAsync(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Six Labors.
|
||||
// Licensed under the Apache License, Version 2.0.
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETSTANDARD2_1 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
#define SUPPORTS_RUNTIME_INTRINSICS
|
||||
#define SUPPORTS_HOTPATH
|
||||
#endif
|
||||
|
||||
@@ -145,6 +145,19 @@ public abstract class AbstractArchive<TEntry, TVolume> : IArchive, IAsyncArchive
|
||||
/// </summary>
|
||||
public virtual bool IsEncrypted => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether multi-threaded extraction is supported for this archive.
|
||||
/// Multi-threading is supported when:
|
||||
/// 1. The archive is opened from a FileInfo or file path (not a stream)
|
||||
/// 2. Multi-threading is explicitly enabled in ReaderOptions
|
||||
/// 3. The archive is not SOLID (SOLID archives should use sequential extraction)
|
||||
/// </summary>
|
||||
public virtual bool SupportsMultiThreadedExtraction =>
|
||||
_sourceStream is not null
|
||||
&& _sourceStream.IsFileMode
|
||||
&& ReaderOptions.EnableMultiThreadedExtraction
|
||||
&& !IsSolid;
|
||||
|
||||
/// <summary>
|
||||
/// The archive can find all the parts of the archive needed to fully extract the archive. This forces the parsing of the entire archive.
|
||||
/// </summary>
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace SharpCompress.Archives;
|
||||
|
||||
public static class ArchiveFactory
|
||||
{
|
||||
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
readerOptions ??= new ReaderOptions();
|
||||
stream = SharpCompressStream.Create(stream, bufferSize: readerOptions.BufferSize);
|
||||
return FindFactory<IArchiveFactory>(stream).Open(stream, readerOptions);
|
||||
return FindFactory<IArchiveFactory>(stream).OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static async ValueTask<IAsyncArchive> OpenAsync(
|
||||
public static async ValueTask<IAsyncArchive> OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -29,10 +29,10 @@ public static class ArchiveFactory
|
||||
readerOptions ??= new ReaderOptions();
|
||||
stream = SharpCompressStream.Create(stream, bufferSize: readerOptions.BufferSize);
|
||||
var factory = await FindFactoryAsync<IArchiveFactory>(stream, cancellationToken);
|
||||
return factory.OpenAsync(stream, readerOptions);
|
||||
return factory.OpenAsyncArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableArchive Create(ArchiveType type)
|
||||
public static IWritableArchive CreateArchive(ArchiveType type)
|
||||
{
|
||||
var factory = Factory
|
||||
.Factories.OfType<IWriteableArchiveFactory>()
|
||||
@@ -40,36 +40,36 @@ public static class ArchiveFactory
|
||||
|
||||
if (factory != null)
|
||||
{
|
||||
return factory.CreateWriteableArchive();
|
||||
return factory.CreateArchive();
|
||||
}
|
||||
|
||||
throw new NotSupportedException("Cannot create Archives of type: " + type);
|
||||
}
|
||||
|
||||
public static IArchive Open(string filePath, ReaderOptions? options = null)
|
||||
public static IArchive OpenArchive(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), options);
|
||||
return OpenArchive(new FileInfo(filePath), options);
|
||||
}
|
||||
|
||||
public static ValueTask<IAsyncArchive> OpenAsync(
|
||||
public static ValueTask<IAsyncArchive> OpenAsyncArchive(
|
||||
string filePath,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return OpenAsync(new FileInfo(filePath), options, cancellationToken);
|
||||
return OpenAsyncArchive(new FileInfo(filePath), options, cancellationToken);
|
||||
}
|
||||
|
||||
public static IArchive Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
public static IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
|
||||
return FindFactory<IArchiveFactory>(fileInfo).Open(fileInfo, options);
|
||||
return FindFactory<IArchiveFactory>(fileInfo).OpenArchive(fileInfo, options);
|
||||
}
|
||||
|
||||
public static async ValueTask<IAsyncArchive> OpenAsync(
|
||||
public static async ValueTask<IAsyncArchive> OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -78,10 +78,13 @@ public static class ArchiveFactory
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
|
||||
var factory = await FindFactoryAsync<IArchiveFactory>(fileInfo, cancellationToken);
|
||||
return factory.OpenAsync(fileInfo, options, cancellationToken);
|
||||
return factory.OpenAsyncArchive(fileInfo, options, cancellationToken);
|
||||
}
|
||||
|
||||
public static IArchive Open(IEnumerable<FileInfo> fileInfos, ReaderOptions? options = null)
|
||||
public static IArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? options = null
|
||||
)
|
||||
{
|
||||
fileInfos.NotNull(nameof(fileInfos));
|
||||
var filesArray = fileInfos.ToArray();
|
||||
@@ -93,16 +96,16 @@ public static class ArchiveFactory
|
||||
var fileInfo = filesArray[0];
|
||||
if (filesArray.Length == 1)
|
||||
{
|
||||
return Open(fileInfo, options);
|
||||
return OpenArchive(fileInfo, options);
|
||||
}
|
||||
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
|
||||
return FindFactory<IMultiArchiveFactory>(fileInfo).Open(filesArray, options);
|
||||
return FindFactory<IMultiArchiveFactory>(fileInfo).OpenArchive(filesArray, options);
|
||||
}
|
||||
|
||||
public static async ValueTask<IAsyncArchive> OpenAsync(
|
||||
public static async ValueTask<IAsyncArchive> OpenAsyncArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -118,17 +121,17 @@ public static class ArchiveFactory
|
||||
var fileInfo = filesArray[0];
|
||||
if (filesArray.Length == 1)
|
||||
{
|
||||
return await OpenAsync(fileInfo, options, cancellationToken);
|
||||
return await OpenAsyncArchive(fileInfo, options, cancellationToken);
|
||||
}
|
||||
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
|
||||
var factory = await FindFactoryAsync<IMultiArchiveFactory>(fileInfo, cancellationToken);
|
||||
return factory.OpenAsync(filesArray, options, cancellationToken);
|
||||
return factory.OpenAsyncArchive(filesArray, options, cancellationToken);
|
||||
}
|
||||
|
||||
public static IArchive Open(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
public static IArchive OpenArchive(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var streamsArray = streams.ToArray();
|
||||
@@ -140,16 +143,16 @@ public static class ArchiveFactory
|
||||
var firstStream = streamsArray[0];
|
||||
if (streamsArray.Length == 1)
|
||||
{
|
||||
return Open(firstStream, options);
|
||||
return OpenArchive(firstStream, options);
|
||||
}
|
||||
|
||||
firstStream.NotNull(nameof(firstStream));
|
||||
options ??= new ReaderOptions();
|
||||
|
||||
return FindFactory<IMultiArchiveFactory>(firstStream).Open(streamsArray, options);
|
||||
return FindFactory<IMultiArchiveFactory>(firstStream).OpenArchive(streamsArray, options);
|
||||
}
|
||||
|
||||
public static async ValueTask<IAsyncArchive> OpenAsync(
|
||||
public static async ValueTask<IAsyncArchive> OpenAsyncArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -166,14 +169,14 @@ public static class ArchiveFactory
|
||||
var firstStream = streamsArray[0];
|
||||
if (streamsArray.Length == 1)
|
||||
{
|
||||
return await OpenAsync(firstStream, options, cancellationToken);
|
||||
return await OpenAsyncArchive(firstStream, options, cancellationToken);
|
||||
}
|
||||
|
||||
firstStream.NotNull(nameof(firstStream));
|
||||
options ??= new ReaderOptions();
|
||||
|
||||
var factory = FindFactory<IMultiArchiveFactory>(firstStream);
|
||||
return factory.OpenAsync(streamsArray, options);
|
||||
return factory.OpenAsyncArchive(streamsArray, options);
|
||||
}
|
||||
|
||||
public static void WriteToDirectory(
|
||||
@@ -182,7 +185,7 @@ public static class ArchiveFactory
|
||||
ExtractionOptions? options = null
|
||||
)
|
||||
{
|
||||
using var archive = Open(sourceArchive);
|
||||
using var archive = OpenArchive(sourceArchive);
|
||||
archive.WriteToDirectory(destinationDirectory, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,22 +31,22 @@ internal class AutoArchiveFactory : IArchiveFactory
|
||||
|
||||
public FileInfo? GetFilePart(int index, FileInfo part1) => throw new NotSupportedException();
|
||||
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.OpenArchive(stream, readerOptions);
|
||||
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
ArchiveFactory.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace SharpCompress.Archives.GZip;
|
||||
|
||||
public partial class GZipArchive
|
||||
#if NET8_0_OR_GREATER
|
||||
: IArchiveOpenable<IWritableArchive, IWritableAsyncArchive>,
|
||||
: IWritableArchiveOpenable,
|
||||
IMultiArchiveOpenable<IWritableArchive, IWritableAsyncArchive>
|
||||
#endif
|
||||
{
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -28,19 +28,22 @@ public partial class GZipArchive
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IWritableAsyncArchive)Open(
|
||||
return (IWritableAsyncArchive)OpenArchive(
|
||||
new FileInfo(path),
|
||||
readerOptions ?? new ReaderOptions()
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new GZipArchive(
|
||||
@@ -52,7 +55,7 @@ public partial class GZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -68,7 +71,7 @@ public partial class GZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -84,7 +87,7 @@ public partial class GZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -98,47 +101,49 @@ public partial class GZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static GZipArchive Create() => new();
|
||||
public static IWritableArchive CreateArchive() => new GZipArchive();
|
||||
|
||||
public static IWritableAsyncArchive CreateAsyncArchive() => new GZipArchive();
|
||||
|
||||
public static bool IsGZipFile(string filePath) => IsGZipFile(new FileInfo(filePath));
|
||||
|
||||
|
||||
@@ -138,13 +138,13 @@ public partial class GZipArchive : AbstractWritableArchive<GZipArchiveEntry, GZi
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
stream.Position = 0;
|
||||
return GZipReader.Open(stream);
|
||||
return GZipReader.OpenReader(stream);
|
||||
}
|
||||
|
||||
protected override ValueTask<IAsyncReader> CreateReaderForSolidExtractionAsync()
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
stream.Position = 0;
|
||||
return new((IAsyncReader)GZipReader.Open(stream));
|
||||
return new((IAsyncReader)GZipReader.OpenReader(stream));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,12 @@ public interface IArchive : IDisposable
|
||||
/// Returns whether the archive is encrypted.
|
||||
/// </summary>
|
||||
bool IsEncrypted { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether multi-threaded extraction is supported for this archive.
|
||||
/// Multi-threading is supported when the archive is opened from a FileInfo or file path
|
||||
/// (not a stream) and the format supports random access (e.g., Zip, Tar, Rar).
|
||||
/// SOLID archives (some Rar, all 7Zip) should use sequential extraction for best performance.
|
||||
/// </summary>
|
||||
bool SupportsMultiThreadedExtraction { get; }
|
||||
}
|
||||
|
||||
@@ -25,21 +25,21 @@ public interface IArchiveFactory : IFactory
|
||||
/// </summary>
|
||||
/// <param name="stream">An open, readable and seekable stream.</param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IArchive Open(Stream stream, ReaderOptions? readerOptions = null);
|
||||
IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Opens an Archive for random access asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="stream">An open, readable and seekable stream.</param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null);
|
||||
IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with a FileInfo object to an existing file.
|
||||
/// </summary>
|
||||
/// <param name="fileInfo">the file to open.</param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null);
|
||||
IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Opens an Archive from a FileInfo object asynchronously.
|
||||
@@ -47,7 +47,7 @@ public interface IArchiveFactory : IFactory
|
||||
/// <param name="fileInfo">the file to open.</param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
IAsyncArchive OpenAsync(
|
||||
IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -9,28 +9,32 @@ public interface IArchiveOpenable<TSync, TASync>
|
||||
where TSync : IArchive
|
||||
where TASync : IAsyncArchive
|
||||
{
|
||||
public static abstract TSync Open(string filePath, ReaderOptions? readerOptions = null);
|
||||
public static abstract TSync OpenArchive(string filePath, ReaderOptions? readerOptions = null);
|
||||
|
||||
public static abstract TSync Open(FileInfo fileInfo, ReaderOptions? readerOptions = null);
|
||||
public static abstract TSync OpenArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null
|
||||
);
|
||||
|
||||
public static abstract TSync Open(Stream stream, ReaderOptions? readerOptions = null);
|
||||
public static abstract TSync OpenArchive(Stream stream, ReaderOptions? readerOptions = null);
|
||||
|
||||
public static abstract TASync OpenAsync(
|
||||
public static abstract TASync OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract TASync OpenAsync(
|
||||
public static abstract TASync OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract TASync OpenAsync(
|
||||
public static abstract TASync OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,21 +26,24 @@ public interface IMultiArchiveFactory : IFactory
|
||||
/// </summary>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null);
|
||||
IArchive OpenArchive(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Opens a multi-part archive from streams asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IAsyncArchive OpenAsync(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null);
|
||||
IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with IEnumerable Stream objects, multi and split support.
|
||||
/// </summary>
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null);
|
||||
IArchive OpenArchive(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null);
|
||||
|
||||
/// <summary>
|
||||
/// Opens a multi-part archive from files asynchronously.
|
||||
@@ -48,7 +51,7 @@ public interface IMultiArchiveFactory : IFactory
|
||||
/// <param name="fileInfos"></param>
|
||||
/// <param name="readerOptions">reading options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
IAsyncArchive OpenAsync(
|
||||
IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -10,23 +10,23 @@ public interface IMultiArchiveOpenable<TSync, TASync>
|
||||
where TSync : IArchive
|
||||
where TASync : IAsyncArchive
|
||||
{
|
||||
public static abstract TSync Open(
|
||||
public static abstract TSync OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
);
|
||||
|
||||
public static abstract TSync Open(
|
||||
public static abstract TSync OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
);
|
||||
|
||||
public static abstract TASync OpenAsync(
|
||||
public static abstract TASync OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract TASync OpenAsync(
|
||||
public static abstract TASync OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -34,6 +34,13 @@ public static class IWritableArchiveCommonExtensions
|
||||
public IArchiveEntry AddEntry(string key, string file) =>
|
||||
writableArchive.AddEntry(key, new FileInfo(file));
|
||||
|
||||
public IArchiveEntry AddEntry(
|
||||
string key,
|
||||
Stream source,
|
||||
long size = 0,
|
||||
DateTime? modified = null
|
||||
) => writableArchive.AddEntry(key, source, false, size, modified);
|
||||
|
||||
public IArchiveEntry AddEntry(string key, FileInfo fileInfo)
|
||||
{
|
||||
if (!fileInfo.Exists)
|
||||
|
||||
10
src/SharpCompress/Archives/IWritableArchiveOpenable.cs
Normal file
10
src/SharpCompress/Archives/IWritableArchiveOpenable.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
#if NET8_0_OR_GREATER
|
||||
namespace SharpCompress.Archives;
|
||||
|
||||
public interface IWritableArchiveOpenable
|
||||
: IArchiveOpenable<IWritableArchive, IWritableAsyncArchive>
|
||||
{
|
||||
public static abstract IWritableArchive CreateArchive();
|
||||
public static abstract IWritableAsyncArchive CreateAsyncArchive();
|
||||
}
|
||||
#endif
|
||||
@@ -16,5 +16,5 @@ public interface IWriteableArchiveFactory : Factories.IFactory
|
||||
/// Creates a new, empty archive, ready to be written.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IWritableArchive CreateWriteableArchive();
|
||||
IWritableArchive CreateArchive();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public partial class RarArchive
|
||||
IMultiArchiveOpenable<IRarArchive, IRarAsyncArchive>
|
||||
#endif
|
||||
{
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -27,10 +27,10 @@ public partial class RarArchive
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IRarAsyncArchive)Open(new FileInfo(path), readerOptions);
|
||||
return (IRarAsyncArchive)OpenArchive(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IRarArchive Open(string filePath, ReaderOptions? options = null)
|
||||
public static IRarArchive OpenArchive(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
var fileInfo = new FileInfo(filePath);
|
||||
@@ -43,7 +43,7 @@ public partial class RarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IRarArchive Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
public static IRarArchive OpenArchive(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new RarArchive(
|
||||
@@ -55,7 +55,7 @@ public partial class RarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IRarArchive Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IRarArchive OpenArchive(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -67,7 +67,7 @@ public partial class RarArchive
|
||||
return new RarArchive(new SourceStream(stream, _ => null, options ?? new ReaderOptions()));
|
||||
}
|
||||
|
||||
public static IRarArchive Open(
|
||||
public static IRarArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -83,7 +83,10 @@ public partial class RarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IRarArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
public static IRarArchive OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams.ToArray();
|
||||
@@ -96,44 +99,44 @@ public partial class RarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IRarAsyncArchive)Open(stream, readerOptions);
|
||||
return (IRarAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IRarAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IRarAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IRarAsyncArchive)Open(streams, readerOptions);
|
||||
return (IRarAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
}
|
||||
|
||||
public static IRarAsyncArchive OpenAsync(
|
||||
public static IRarAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IRarAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IRarAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsRarFile(string filePath) => IsRarFile(new FileInfo(filePath));
|
||||
|
||||
@@ -101,12 +101,12 @@ public partial class RarArchive : AbstractArchive<RarArchiveEntry, RarVolume>, I
|
||||
volume.Stream.Position = 0;
|
||||
return volume.Stream;
|
||||
});
|
||||
return (RarReader)RarReader.Open(streams, ReaderOptions);
|
||||
return (RarReader)RarReader.OpenReader(streams, ReaderOptions);
|
||||
}
|
||||
|
||||
var stream = Volumes.First().Stream;
|
||||
stream.Position = 0;
|
||||
return (RarReader)RarReader.Open(stream, ReaderOptions);
|
||||
return (RarReader)RarReader.OpenReader(stream, ReaderOptions);
|
||||
}
|
||||
|
||||
public override bool IsSolid => Volumes.First().IsSolidArchive;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Rar;
|
||||
using SharpCompress.Common.Rar.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Archives.Rar;
|
||||
|
||||
@@ -24,6 +25,76 @@ internal class SeekableFilePart : RarFilePart
|
||||
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
Stream streamToUse;
|
||||
|
||||
// If the stream is a SourceStream in file mode with multi-threading enabled,
|
||||
// create an independent stream to support concurrent extraction
|
||||
if (
|
||||
_stream is SourceStream sourceStream
|
||||
&& sourceStream.IsFileMode
|
||||
&& sourceStream.ReaderOptions.EnableMultiThreadedExtraction
|
||||
)
|
||||
{
|
||||
var independentStream = sourceStream.CreateIndependentStream(0);
|
||||
if (independentStream is not null)
|
||||
{
|
||||
streamToUse = independentStream;
|
||||
streamToUse.Position = FileHeader.DataStartPosition;
|
||||
|
||||
if (FileHeader.R4Salt != null)
|
||||
{
|
||||
var cryptKey = new CryptKey3(_password!);
|
||||
return new RarCryptoWrapper(streamToUse, FileHeader.R4Salt, cryptKey);
|
||||
}
|
||||
|
||||
if (FileHeader.Rar5CryptoInfo != null)
|
||||
{
|
||||
var cryptKey = new CryptKey5(_password!, FileHeader.Rar5CryptoInfo);
|
||||
return new RarCryptoWrapper(
|
||||
streamToUse,
|
||||
FileHeader.Rar5CryptoInfo.Salt,
|
||||
cryptKey
|
||||
);
|
||||
}
|
||||
|
||||
return streamToUse;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the stream wraps a FileStream
|
||||
Stream? underlyingStream = _stream;
|
||||
if (_stream is IStreamStack streamStack)
|
||||
{
|
||||
underlyingStream = streamStack.BaseStream();
|
||||
}
|
||||
|
||||
if (underlyingStream is FileStream fileStream)
|
||||
{
|
||||
// Create a new independent stream from the file
|
||||
streamToUse = new FileStream(
|
||||
fileStream.Name,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
);
|
||||
streamToUse.Position = FileHeader.DataStartPosition;
|
||||
|
||||
if (FileHeader.R4Salt != null)
|
||||
{
|
||||
var cryptKey = new CryptKey3(_password!);
|
||||
return new RarCryptoWrapper(streamToUse, FileHeader.R4Salt, cryptKey);
|
||||
}
|
||||
|
||||
if (FileHeader.Rar5CryptoInfo != null)
|
||||
{
|
||||
var cryptKey = new CryptKey5(_password!, FileHeader.Rar5CryptoInfo);
|
||||
return new RarCryptoWrapper(streamToUse, FileHeader.Rar5CryptoInfo.Salt, cryptKey);
|
||||
}
|
||||
|
||||
return streamToUse;
|
||||
}
|
||||
|
||||
// Fall back to existing behavior for stream-based sources
|
||||
_stream.Position = FileHeader.DataStartPosition;
|
||||
|
||||
if (FileHeader.R4Salt != null)
|
||||
|
||||
@@ -18,7 +18,7 @@ public partial class SevenZipArchive
|
||||
IMultiArchiveOpenable<IArchive, IAsyncArchive>
|
||||
#endif
|
||||
{
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IAsyncArchive OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -26,16 +26,16 @@ public partial class SevenZipArchive
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty("path");
|
||||
return (IAsyncArchive)Open(new FileInfo(path), readerOptions ?? new ReaderOptions());
|
||||
return (IAsyncArchive)OpenArchive(new FileInfo(path), readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty("filePath");
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull("fileInfo");
|
||||
return new SevenZipArchive(
|
||||
@@ -47,7 +47,7 @@ public partial class SevenZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IArchive Open(
|
||||
public static IArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -63,7 +63,10 @@ public partial class SevenZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IArchive Open(IEnumerable<Stream> streams, ReaderOptions? readerOptions = null)
|
||||
public static IArchive OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams.ToArray();
|
||||
@@ -76,7 +79,7 @@ public partial class SevenZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull("stream");
|
||||
|
||||
@@ -90,44 +93,44 @@ public partial class SevenZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IAsyncArchive OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(stream, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(streams, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncArchive OpenAsync(
|
||||
public static IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsSevenZipFile(string filePath) => IsSevenZipFile(new FileInfo(filePath));
|
||||
|
||||
@@ -184,7 +184,7 @@ public partial class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, Sev
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -16,17 +16,20 @@ namespace SharpCompress.Archives.Tar;
|
||||
|
||||
public partial class TarArchive
|
||||
#if NET8_0_OR_GREATER
|
||||
: IArchiveOpenable<IWritableArchive, IWritableAsyncArchive>,
|
||||
: IWritableArchiveOpenable,
|
||||
IMultiArchiveOpenable<IWritableArchive, IWritableAsyncArchive>
|
||||
#endif
|
||||
{
|
||||
public static IWritableArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new TarArchive(
|
||||
@@ -38,7 +41,7 @@ public partial class TarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -54,7 +57,7 @@ public partial class TarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -70,7 +73,7 @@ public partial class TarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -84,54 +87,54 @@ public partial class TarArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(new FileInfo(path), readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsTarFile(string filePath) => IsTarFile(new FileInfo(filePath));
|
||||
@@ -162,5 +165,7 @@ public partial class TarArchive
|
||||
return false;
|
||||
}
|
||||
|
||||
public static TarArchive Create() => new();
|
||||
public static IWritableArchive CreateArchive() => new TarArchive();
|
||||
|
||||
public static IWritableAsyncArchive CreateAsyncArchive() => new TarArchive();
|
||||
}
|
||||
|
||||
@@ -180,13 +180,13 @@ public partial class TarArchive : AbstractWritableArchive<TarArchiveEntry, TarVo
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
stream.Position = 0;
|
||||
return TarReader.Open(stream);
|
||||
return TarReader.OpenReader(stream);
|
||||
}
|
||||
|
||||
protected override ValueTask<IAsyncReader> CreateReaderForSolidExtractionAsync()
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
stream.Position = 0;
|
||||
return new((IAsyncReader)TarReader.Open(stream));
|
||||
return new((IAsyncReader)TarReader.OpenReader(stream));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,17 +14,20 @@ namespace SharpCompress.Archives.Zip;
|
||||
|
||||
public partial class ZipArchive
|
||||
#if NET8_0_OR_GREATER
|
||||
: IArchiveOpenable<IWritableArchive, IWritableAsyncArchive>,
|
||||
: IWritableArchiveOpenable,
|
||||
IMultiArchiveOpenable<IWritableArchive, IWritableAsyncArchive>
|
||||
#endif
|
||||
{
|
||||
public static IWritableArchive Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
return OpenArchive(new FileInfo(filePath), readerOptions ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new ZipArchive(
|
||||
@@ -36,7 +39,7 @@ public partial class ZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -52,7 +55,7 @@ public partial class ZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(
|
||||
public static IWritableArchive OpenArchive(
|
||||
IEnumerable<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
@@ -68,7 +71,7 @@ public partial class ZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableArchive Open(Stream stream, ReaderOptions? readerOptions = null)
|
||||
public static IWritableArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
@@ -82,54 +85,54 @@ public partial class ZipArchive
|
||||
);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(path, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(path, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(stream, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(streams, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
}
|
||||
|
||||
public static IWritableAsyncArchive OpenAsync(
|
||||
public static IWritableAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IWritableAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IWritableAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
public static bool IsZipFile(
|
||||
@@ -263,7 +266,9 @@ public partial class ZipArchive
|
||||
}
|
||||
}
|
||||
|
||||
public static ZipArchive Create() => new();
|
||||
public static IWritableArchive CreateArchive() => new ZipArchive();
|
||||
|
||||
public static IWritableAsyncArchive CreateAsyncArchive() => new ZipArchive();
|
||||
|
||||
public static async ValueTask<bool> IsZipMultiAsync(
|
||||
Stream stream,
|
||||
|
||||
@@ -244,13 +244,13 @@ public partial class ZipArchive : AbstractWritableArchive<ZipArchiveEntry, ZipVo
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
((IStreamStack)stream).StackSeek(0);
|
||||
return ZipReader.Open(stream, ReaderOptions, Entries);
|
||||
return ZipReader.OpenReader(stream, ReaderOptions, Entries);
|
||||
}
|
||||
|
||||
protected override ValueTask<IAsyncReader> CreateReaderForSolidExtractionAsync()
|
||||
{
|
||||
var stream = Volumes.Single().Stream;
|
||||
stream.Position = 0;
|
||||
return new((IAsyncReader)ZipReader.Open(stream));
|
||||
return new((IAsyncReader)ZipReader.OpenReader(stream));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +51,19 @@ namespace SharpCompress.Common
|
||||
return BinaryPrimitives.ReadUInt64LittleEndian(_buffer);
|
||||
}
|
||||
|
||||
public async ValueTask ReadBytesAsync(byte[] bytes, int offset, int count, CancellationToken ct = default)
|
||||
public async ValueTask ReadBytesAsync(
|
||||
byte[] bytes,
|
||||
int offset,
|
||||
int count,
|
||||
CancellationToken ct = default
|
||||
)
|
||||
{
|
||||
await _stream.ReadExactAsync(bytes, offset, count, ct).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async ValueTask SkipAsync(int count, CancellationToken ct = default)
|
||||
{
|
||||
await _stream.SkipAsync( count, ct).ConfigureAwait(false);
|
||||
await _stream.SkipAsync(count, ct).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -77,7 +82,7 @@ namespace SharpCompress.Common
|
||||
}
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NET8_0_OR_GREATER
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_disposed)
|
||||
|
||||
@@ -93,7 +93,7 @@ public class EntryStream : Stream, IStreamStack
|
||||
_stream.Dispose();
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_isDisposed)
|
||||
@@ -171,7 +171,7 @@ public class EntryStream : Stream, IStreamStack
|
||||
return read;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Tar.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Common.Tar;
|
||||
|
||||
@@ -20,8 +21,45 @@ internal sealed class TarFilePart : FilePart
|
||||
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (_seekableStream != null)
|
||||
if (_seekableStream is not null)
|
||||
{
|
||||
// If the seekable stream is a SourceStream in file mode with multi-threading enabled,
|
||||
// create an independent stream to support concurrent extraction
|
||||
if (
|
||||
_seekableStream is SourceStream sourceStream
|
||||
&& sourceStream.IsFileMode
|
||||
&& sourceStream.ReaderOptions.EnableMultiThreadedExtraction
|
||||
)
|
||||
{
|
||||
var independentStream = sourceStream.CreateIndependentStream(0);
|
||||
if (independentStream is not null)
|
||||
{
|
||||
independentStream.Position = Header.DataStartPosition ?? 0;
|
||||
return new TarReadOnlySubStream(independentStream, Header.Size);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the seekable stream wraps a FileStream
|
||||
Stream? underlyingStream = _seekableStream;
|
||||
if (_seekableStream is IStreamStack streamStack)
|
||||
{
|
||||
underlyingStream = streamStack.BaseStream();
|
||||
}
|
||||
|
||||
if (underlyingStream is FileStream fileStream)
|
||||
{
|
||||
// Create a new independent stream from the file
|
||||
var independentStream = new FileStream(
|
||||
fileStream.Name,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
);
|
||||
independentStream.Position = Header.DataStartPosition ?? 0;
|
||||
return new TarReadOnlySubStream(independentStream, Header.Size);
|
||||
}
|
||||
|
||||
// Fall back to existing behavior for stream-based sources
|
||||
_seekableStream.Position = Header.DataStartPosition ?? 0;
|
||||
return new TarReadOnlySubStream(_seekableStream, Header.Size);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ internal class TarReadOnlySubStream : SharpCompressStream, IStreamStack
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask DisposeAsync()
|
||||
{
|
||||
if (_isDisposed)
|
||||
@@ -170,7 +170,7 @@ internal class TarReadOnlySubStream : SharpCompressStream, IStreamStack
|
||||
return read;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask<int> ReadAsync(
|
||||
System.Memory<byte> buffer,
|
||||
System.Threading.CancellationToken cancellationToken = default
|
||||
|
||||
@@ -56,7 +56,7 @@ internal class DirectoryEntryHeader : ZipFileEntry
|
||||
var name = new byte[nameLength];
|
||||
var extra = new byte[extraLength];
|
||||
var comment = new byte[commentLength];
|
||||
await reader.ReadBytesAsync(name,0 ,nameLength);
|
||||
await reader.ReadBytesAsync(name, 0, nameLength);
|
||||
await reader.ReadBytesAsync(extra, 0, extraLength);
|
||||
await reader.ReadBytesAsync(comment, 0, commentLength);
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ internal class LocalEntryHeader(IArchiveEncoding archiveEncoding)
|
||||
var extraLength = await reader.ReadUInt16Async();
|
||||
var name = new byte[nameLength];
|
||||
var extra = new byte[extraLength];
|
||||
await reader.ReadBytesAsync(name,0 ,nameLength);
|
||||
await reader.ReadBytesAsync(extra, 0, extraLength);
|
||||
await reader.ReadBytesAsync(name, 0, nameLength);
|
||||
await reader.ReadBytesAsync(extra, 0, extraLength);
|
||||
|
||||
ProcessReadData(name, extra);
|
||||
}
|
||||
|
||||
@@ -39,11 +39,10 @@ internal class Zip64DirectoryEndHeader : ZipHeader
|
||||
DirectorySize = (long)await reader.ReadUInt64Async();
|
||||
DirectoryStartOffsetRelativeToDisk = (long)await reader.ReadUInt64Async();
|
||||
var size = (int)(
|
||||
SizeOfDirectoryEndRecord
|
||||
- SIZE_OF_FIXED_HEADER_DATA_EXCEPT_SIGNATURE_AND_SIZE_FIELDS
|
||||
SizeOfDirectoryEndRecord - SIZE_OF_FIXED_HEADER_DATA_EXCEPT_SIGNATURE_AND_SIZE_FIELDS
|
||||
);
|
||||
DataSector = new byte[size];
|
||||
await reader.ReadBytesAsync(DataSector, 0, size);
|
||||
await reader.ReadBytesAsync(DataSector, 0, size);
|
||||
}
|
||||
|
||||
private const int SIZE_OF_FIXED_HEADER_DATA_EXCEPT_SIGNATURE_AND_SIZE_FIELDS = 44;
|
||||
|
||||
@@ -2,13 +2,16 @@ using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common.Zip.Headers;
|
||||
using SharpCompress.IO;
|
||||
|
||||
namespace SharpCompress.Common.Zip;
|
||||
|
||||
internal class SeekableZipFilePart : ZipFilePart
|
||||
{
|
||||
private bool _isLocalHeaderLoaded;
|
||||
private volatile bool _isLocalHeaderLoaded;
|
||||
private readonly SeekableZipHeaderFactory _headerFactory;
|
||||
private readonly object _headerLock = new();
|
||||
private readonly SemaphoreSlim _asyncHeaderSemaphore = new(1, 1);
|
||||
|
||||
internal SeekableZipFilePart(
|
||||
SeekableZipHeaderFactory headerFactory,
|
||||
@@ -21,8 +24,14 @@ internal class SeekableZipFilePart : ZipFilePart
|
||||
{
|
||||
if (!_isLocalHeaderLoaded)
|
||||
{
|
||||
LoadLocalHeader();
|
||||
_isLocalHeaderLoaded = true;
|
||||
lock (_headerLock)
|
||||
{
|
||||
if (!_isLocalHeaderLoaded)
|
||||
{
|
||||
LoadLocalHeader();
|
||||
_isLocalHeaderLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.GetCompressedStream();
|
||||
}
|
||||
@@ -33,22 +42,173 @@ internal class SeekableZipFilePart : ZipFilePart
|
||||
{
|
||||
if (!_isLocalHeaderLoaded)
|
||||
{
|
||||
await LoadLocalHeaderAsync(cancellationToken);
|
||||
_isLocalHeaderLoaded = true;
|
||||
await _asyncHeaderSemaphore.WaitAsync(cancellationToken);
|
||||
try
|
||||
{
|
||||
if (!_isLocalHeaderLoaded)
|
||||
{
|
||||
await LoadLocalHeaderAsync(cancellationToken);
|
||||
_isLocalHeaderLoaded = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_asyncHeaderSemaphore.Release();
|
||||
}
|
||||
}
|
||||
return await base.GetCompressedStreamAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private void LoadLocalHeader() =>
|
||||
Header = _headerFactory.GetLocalHeader(BaseStream, (DirectoryEntryHeader)Header);
|
||||
private void LoadLocalHeader()
|
||||
{
|
||||
// Use an independent stream for loading the header if multi-threading is enabled
|
||||
Stream streamToUse = BaseStream;
|
||||
bool disposeStream = false;
|
||||
|
||||
private async ValueTask LoadLocalHeaderAsync(CancellationToken cancellationToken = default) =>
|
||||
Header = await _headerFactory.GetLocalHeaderAsync(BaseStream, (DirectoryEntryHeader)Header);
|
||||
if (
|
||||
BaseStream is SourceStream sourceStream
|
||||
&& sourceStream.IsFileMode
|
||||
&& sourceStream.ReaderOptions.EnableMultiThreadedExtraction
|
||||
)
|
||||
{
|
||||
var independentStream = sourceStream.CreateIndependentStream(0);
|
||||
if (independentStream is not null)
|
||||
{
|
||||
streamToUse = independentStream;
|
||||
disposeStream = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if BaseStream wraps a FileStream
|
||||
Stream? underlyingStream = BaseStream;
|
||||
if (BaseStream is IStreamStack streamStack)
|
||||
{
|
||||
underlyingStream = streamStack.BaseStream();
|
||||
}
|
||||
|
||||
if (underlyingStream is FileStream fileStream)
|
||||
{
|
||||
streamToUse = new FileStream(
|
||||
fileStream.Name,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
);
|
||||
disposeStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Header = _headerFactory.GetLocalHeader(streamToUse, (DirectoryEntryHeader)Header);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (disposeStream)
|
||||
{
|
||||
streamToUse.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask LoadLocalHeaderAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Use an independent stream for loading the header if multi-threading is enabled
|
||||
Stream streamToUse = BaseStream;
|
||||
bool disposeStream = false;
|
||||
|
||||
if (
|
||||
BaseStream is SourceStream sourceStream
|
||||
&& sourceStream.IsFileMode
|
||||
&& sourceStream.ReaderOptions.EnableMultiThreadedExtraction
|
||||
)
|
||||
{
|
||||
var independentStream = sourceStream.CreateIndependentStream(0);
|
||||
if (independentStream is not null)
|
||||
{
|
||||
streamToUse = independentStream;
|
||||
disposeStream = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if BaseStream wraps a FileStream
|
||||
Stream? underlyingStream = BaseStream;
|
||||
if (BaseStream is IStreamStack streamStack)
|
||||
{
|
||||
underlyingStream = streamStack.BaseStream();
|
||||
}
|
||||
|
||||
if (underlyingStream is FileStream fileStream)
|
||||
{
|
||||
streamToUse = new FileStream(
|
||||
fileStream.Name,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
);
|
||||
disposeStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Header = await _headerFactory.GetLocalHeaderAsync(
|
||||
streamToUse,
|
||||
(DirectoryEntryHeader)Header
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (disposeStream)
|
||||
{
|
||||
streamToUse.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Stream CreateBaseStream()
|
||||
{
|
||||
BaseStream.Position = Header.DataStartPosition.NotNull();
|
||||
// If BaseStream is a SourceStream in file mode with multi-threading enabled,
|
||||
// create an independent stream to support concurrent extraction
|
||||
if (
|
||||
BaseStream is SourceStream sourceStream
|
||||
&& sourceStream.IsFileMode
|
||||
&& sourceStream.ReaderOptions.EnableMultiThreadedExtraction
|
||||
)
|
||||
{
|
||||
// Create a new independent stream for this entry
|
||||
var independentStream = sourceStream.CreateIndependentStream(0);
|
||||
if (independentStream is not null)
|
||||
{
|
||||
independentStream.Position = Header.DataStartPosition.NotNull();
|
||||
return independentStream;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if BaseStream wraps a FileStream (for multi-volume archives)
|
||||
Stream? underlyingStream = BaseStream;
|
||||
if (BaseStream is IStreamStack streamStack)
|
||||
{
|
||||
underlyingStream = streamStack.BaseStream();
|
||||
}
|
||||
|
||||
if (underlyingStream is FileStream fileStream)
|
||||
{
|
||||
// Create a new independent stream from the file
|
||||
var independentStream = new FileStream(
|
||||
fileStream.Name,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
);
|
||||
independentStream.Position = Header.DataStartPosition.NotNull();
|
||||
return independentStream;
|
||||
}
|
||||
|
||||
// Fall back to existing behavior for stream-based sources
|
||||
BaseStream.Position = Header.DataStartPosition.NotNull();
|
||||
return BaseStream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,6 @@ internal sealed class SeekableZipHeaderFactory : ZipHeaderFactory
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool IsMatch(Span<byte> haystack, int position, byte[] needle)
|
||||
{
|
||||
for (var i = 0; i < needle.Length; i++)
|
||||
|
||||
@@ -20,7 +20,7 @@ internal class WinzipAesEncryptionData
|
||||
{
|
||||
_keySize = keySize;
|
||||
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0
|
||||
#if LEGACY_DOTNET
|
||||
var rfc2898 = new Rfc2898DeriveBytes(password, salt, RFC2898_ITERATIONS);
|
||||
KeyBytes = rfc2898.GetBytes(KeySizeInBytes);
|
||||
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
|
||||
|
||||
@@ -98,7 +98,7 @@ public sealed class BZip2Stream : Stream, IStreamStack
|
||||
|
||||
public override void SetLength(long value) => stream.SetLength(value);
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override int Read(Span<byte> buffer) => stream.Read(buffer);
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ public class DeflateStream : Stream, IStreamStack
|
||||
await _baseStream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -370,7 +370,7 @@ public class DeflateStream : Stream, IStreamStack
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -461,7 +461,7 @@ public class DeflateStream : Stream, IStreamStack
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask WriteAsync(
|
||||
ReadOnlyMemory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -345,7 +345,7 @@ public class GZipStream : Stream, IStreamStack
|
||||
return n;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -454,7 +454,7 @@ public class GZipStream : Stream, IStreamStack
|
||||
await BaseStream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask WriteAsync(
|
||||
ReadOnlyMemory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -776,11 +776,16 @@ internal sealed class InflateBlocks
|
||||
// update check information
|
||||
if (checkfn != null)
|
||||
{
|
||||
_codec._adler32 = check = Adler32.Calculate(check, window.Memory.Span.Slice(readAt, nBytes));
|
||||
_codec._adler32 = check = Adler32.Calculate(
|
||||
check,
|
||||
window.Memory.Span.Slice(readAt, nBytes)
|
||||
);
|
||||
}
|
||||
|
||||
// copy as far as end of window
|
||||
window.Memory.Span.Slice(readAt, nBytes).CopyTo(_codec.OutputBuffer.AsSpan(_codec.NextOut));
|
||||
window
|
||||
.Memory.Span.Slice(readAt, nBytes)
|
||||
.CopyTo(_codec.OutputBuffer.AsSpan(_codec.NextOut));
|
||||
_codec.NextOut += nBytes;
|
||||
readAt += nBytes;
|
||||
|
||||
@@ -1469,7 +1474,8 @@ internal sealed class InflateCodes
|
||||
}
|
||||
else
|
||||
{
|
||||
s.window.Memory.Span.Slice(r, 2).CopyTo(s.window.Memory.Span.Slice(q));
|
||||
s.window.Memory.Span.Slice(r, 2)
|
||||
.CopyTo(s.window.Memory.Span.Slice(q));
|
||||
q += 2;
|
||||
r += 2;
|
||||
c -= 2;
|
||||
@@ -1497,7 +1503,8 @@ internal sealed class InflateCodes
|
||||
}
|
||||
else
|
||||
{
|
||||
s.window.Memory.Span.Slice(r, e).CopyTo(s.window.Memory.Span.Slice(q));
|
||||
s.window.Memory.Span.Slice(r, e)
|
||||
.CopyTo(s.window.Memory.Span.Slice(q));
|
||||
q += e;
|
||||
r += e;
|
||||
e = 0;
|
||||
@@ -1516,7 +1523,8 @@ internal sealed class InflateCodes
|
||||
}
|
||||
else
|
||||
{
|
||||
s.window.Memory.Span.Slice(r, c).CopyTo(s.window.Memory.Span.Slice(q));
|
||||
s.window.Memory.Span.Slice(r, c)
|
||||
.CopyTo(s.window.Memory.Span.Slice(q));
|
||||
q += c;
|
||||
r += c;
|
||||
c = 0;
|
||||
|
||||
@@ -552,7 +552,7 @@ internal class ZlibBaseStream : Stream, IStreamStack
|
||||
}
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (isDisposed)
|
||||
@@ -1171,7 +1171,7 @@ internal class ZlibBaseStream : Stream, IStreamStack
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -108,13 +108,9 @@ internal static class ZlibConstants
|
||||
public const int Z_BUF_ERROR = -5;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
|
||||
/// The size of the working buffer used in the ZlibCodec class. Defaults to 16384 bytes.
|
||||
/// </summary>
|
||||
#if NETCF
|
||||
public const int WorkingBufferSizeDefault = 8192;
|
||||
#else
|
||||
public const int WorkingBufferSizeDefault = 16384;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes.
|
||||
|
||||
@@ -277,7 +277,7 @@ public class ZlibStream : Stream, IStreamStack
|
||||
await _baseStream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -347,7 +347,7 @@ public class ZlibStream : Stream, IStreamStack
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -431,7 +431,7 @@ public class ZlibStream : Stream, IStreamStack
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask WriteAsync(
|
||||
ReadOnlyMemory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -200,7 +200,7 @@ public sealed class Deflate64Stream : Stream, IStreamStack
|
||||
return count - remainingCount;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -163,7 +163,7 @@ public sealed class LZipStream : Stream, IStreamStack
|
||||
|
||||
public override void SetLength(long value) => throw new NotImplementedException();
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
|
||||
@@ -201,7 +201,7 @@ public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
|
||||
}
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
[MemberNotNull(nameof(_outWindow))]
|
||||
#endif
|
||||
private void CreateDictionary()
|
||||
|
||||
@@ -632,7 +632,7 @@ public class LzmaStream : Stream, IStreamStack
|
||||
return total;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -185,7 +185,7 @@ internal sealed class MultiVolumeReadOnlyStream : Stream, IStreamStack
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
System.Threading.CancellationToken cancellationToken = default
|
||||
|
||||
@@ -385,7 +385,7 @@ internal class RarBLAKE2spStream : RarStream, IStreamStack
|
||||
return result;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
System.Threading.CancellationToken cancellationToken = default
|
||||
|
||||
@@ -129,7 +129,7 @@ internal class RarCrcStream : RarStream, IStreamStack
|
||||
return result;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
System.Threading.CancellationToken cancellationToken = default
|
||||
|
||||
@@ -189,7 +189,7 @@ internal class RarStream : Stream, IStreamStack
|
||||
return outTotal;
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||
#if !LEGACY_DOTNET
|
||||
public override async System.Threading.Tasks.ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
System.Threading.CancellationToken cancellationToken = default
|
||||
|
||||
@@ -126,7 +126,6 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
|
||||
|
||||
private FileHeader fileHeader;
|
||||
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (this.window is null)
|
||||
|
||||
@@ -74,7 +74,7 @@ public class CompressionStream : Stream
|
||||
|
||||
~CompressionStream() => Dispose(false);
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
#else
|
||||
public async ValueTask DisposeAsync()
|
||||
@@ -145,7 +145,7 @@ public class CompressionStream : Stream
|
||||
public override void Write(byte[] buffer, int offset, int count) =>
|
||||
Write(new ReadOnlySpan<byte>(buffer, offset, count));
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
public override void Write(ReadOnlySpan<byte> buffer) =>
|
||||
WriteInternal(buffer, ZSTD_EndDirective.ZSTD_e_continue);
|
||||
#else
|
||||
@@ -176,7 +176,7 @@ public class CompressionStream : Stream
|
||||
);
|
||||
}
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
private async ValueTask WriteInternalAsync(
|
||||
ReadOnlyMemory<byte>? buffer,
|
||||
ZSTD_EndDirective directive,
|
||||
@@ -218,7 +218,7 @@ public class CompressionStream : Stream
|
||||
);
|
||||
}
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override Task WriteAsync(
|
||||
byte[] buffer,
|
||||
|
||||
@@ -105,7 +105,7 @@ public class DecompressionStream : Stream
|
||||
public override int Read(byte[] buffer, int offset, int count) =>
|
||||
Read(new Span<byte>(buffer, offset, count));
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
public override int Read(Span<byte> buffer)
|
||||
#else
|
||||
public int Read(Span<byte> buffer)
|
||||
@@ -158,7 +158,7 @@ public class DecompressionStream : Stream
|
||||
}
|
||||
}
|
||||
|
||||
#if !NETSTANDARD2_0 && !NETFRAMEWORK
|
||||
#if !LEGACY_DOTNET
|
||||
public override Task<int> ReadAsync(
|
||||
byte[] buffer,
|
||||
int offset,
|
||||
@@ -276,7 +276,7 @@ public class DecompressionStream : Stream
|
||||
throw new ObjectDisposedException(nameof(DecompressionStream));
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0 || NETFRAMEWORK
|
||||
#if LEGACY_DOTNET
|
||||
public virtual Task DisposeAsync()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -16,7 +16,7 @@ public static unsafe class UnsafeHelper
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void* malloc(ulong size)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NET8_0_OR_GREATER
|
||||
var ptr = NativeMemory.Alloc((nuint)size);
|
||||
#else
|
||||
var ptr = (void*)Marshal.AllocHGlobal((nint)size);
|
||||
@@ -31,7 +31,7 @@ public static unsafe class UnsafeHelper
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void* calloc(ulong num, ulong size)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NET8_0_OR_GREATER
|
||||
return NativeMemory.AllocZeroed((nuint)num, (nuint)size);
|
||||
#else
|
||||
var total = num * size;
|
||||
@@ -53,7 +53,7 @@ public static unsafe class UnsafeHelper
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void free(void* ptr)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NET8_0_OR_GREATER
|
||||
NativeMemory.Free(ptr);
|
||||
#else
|
||||
Marshal.FreeHGlobal((IntPtr)ptr);
|
||||
|
||||
@@ -70,7 +70,7 @@ public sealed class Crc32Stream : Stream, IStreamStack
|
||||
|
||||
public override void SetLength(long value) => throw new NotSupportedException();
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override void Write(ReadOnlySpan<byte> buffer)
|
||||
{
|
||||
|
||||
@@ -30,16 +30,16 @@ namespace SharpCompress.Factories
|
||||
) => AceHeader.IsArchive(stream);
|
||||
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
AceReader.Open(stream, options);
|
||||
AceReader.OpenReader(stream, options);
|
||||
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)AceReader.Open(stream, options);
|
||||
return (IAsyncReader)AceReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
|
||||
@@ -42,16 +42,16 @@ namespace SharpCompress.Factories
|
||||
}
|
||||
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
ArcReader.Open(stream, options);
|
||||
ArcReader.OpenReader(stream, options);
|
||||
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)ArcReader.Open(stream, options);
|
||||
return (IAsyncReader)ArcReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
|
||||
@@ -33,16 +33,16 @@ namespace SharpCompress.Factories
|
||||
}
|
||||
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
ArjReader.Open(stream, options);
|
||||
ArjReader.OpenReader(stream, options);
|
||||
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)ArjReader.Open(stream, options);
|
||||
return (IAsyncReader)ArjReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
|
||||
@@ -133,7 +133,7 @@ public abstract class Factory : IFactory
|
||||
)
|
||||
{
|
||||
((IStreamStack)stream).StackSeek(pos);
|
||||
return (true, readerFactory.OpenReaderAsync(stream, options, cancellationToken));
|
||||
return (true, readerFactory.OpenAsyncReader(stream, options, cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ public class GZipFactory
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
Stream stream,
|
||||
@@ -75,14 +75,14 @@ public class GZipFactory
|
||||
) => new(IsArchive(stream, password, bufferSize));
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -90,28 +90,32 @@ public class GZipFactory
|
||||
#region IMultiArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.Open(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)Open(streams, readerOptions);
|
||||
) => GZipArchive.OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.Open(fileInfos, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => GZipArchive.OpenArchive(fileInfos, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -150,29 +154,29 @@ public class GZipFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
GZipReader.Open(stream, options);
|
||||
GZipReader.OpenReader(stream, options);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)GZipReader.Open(stream, options);
|
||||
return (IAsyncReader)GZipReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
GZipArchive.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
#endregion
|
||||
|
||||
#region IWriterFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWriter Open(Stream stream, WriterOptions writerOptions)
|
||||
public IWriter OpenWriter(Stream stream, WriterOptions writerOptions)
|
||||
{
|
||||
if (writerOptions.CompressionType != CompressionType.GZip)
|
||||
{
|
||||
@@ -182,7 +186,7 @@ public class GZipFactory
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncWriter OpenAsync(
|
||||
public IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
WriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -193,7 +197,7 @@ public class GZipFactory
|
||||
{
|
||||
throw new InvalidFormatException("GZip archives only support GZip compression type.");
|
||||
}
|
||||
return (IAsyncWriter)Open(stream, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -201,7 +205,7 @@ public class GZipFactory
|
||||
#region IWriteableArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWritableArchive CreateWriteableArchive() => GZipArchive.Create();
|
||||
public IWritableArchive CreateArchive() => GZipArchive.CreateArchive();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -46,26 +46,26 @@ public class RarFactory : Factory, IArchiveFactory, IMultiArchiveFactory, IReade
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
@@ -79,28 +79,32 @@ public class RarFactory : Factory, IArchiveFactory, IMultiArchiveFactory, IReade
|
||||
#region IMultiArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.Open(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)Open(streams, readerOptions);
|
||||
) => RarArchive.OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null) =>
|
||||
RarArchive.Open(fileInfos, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => RarArchive.OpenArchive(fileInfos, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -109,17 +113,17 @@ public class RarFactory : Factory, IArchiveFactory, IMultiArchiveFactory, IReade
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
RarReader.Open(stream, options);
|
||||
RarReader.OpenReader(stream, options);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)RarReader.Open(stream, options);
|
||||
return (IAsyncReader)RarReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -41,26 +41,26 @@ public class SevenZipFactory : Factory, IArchiveFactory, IMultiArchiveFactory
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public override ValueTask<bool> IsArchiveAsync(
|
||||
@@ -74,28 +74,32 @@ public class SevenZipFactory : Factory, IArchiveFactory, IMultiArchiveFactory
|
||||
#region IMultiArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.Open(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)Open(streams, readerOptions);
|
||||
) => SevenZipArchive.OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null) =>
|
||||
SevenZipArchive.Open(fileInfos, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => SevenZipArchive.OpenArchive(fileInfos, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -72,26 +72,26 @@ public class TarFactory
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -99,28 +99,32 @@ public class TarFactory
|
||||
#region IMultiArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.Open(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)Open(streams, readerOptions);
|
||||
) => TarArchive.OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null) =>
|
||||
TarArchive.Open(fileInfos, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => TarArchive.OpenArchive(fileInfos, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -272,17 +276,17 @@ public class TarFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
TarReader.Open(stream, options);
|
||||
TarReader.OpenReader(stream, options);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)TarReader.Open(stream, options);
|
||||
return (IAsyncReader)TarReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -290,18 +294,18 @@ public class TarFactory
|
||||
#region IWriterFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWriter Open(Stream stream, WriterOptions writerOptions) =>
|
||||
public IWriter OpenWriter(Stream stream, WriterOptions writerOptions) =>
|
||||
new TarWriter(stream, new TarWriterOptions(writerOptions));
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncWriter OpenAsync(
|
||||
public IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
WriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncWriter)Open(stream, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -309,7 +313,7 @@ public class TarFactory
|
||||
#region IWriteableArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWritableArchive CreateWriteableArchive() => TarArchive.Create();
|
||||
public IWritableArchive CreateArchive() => TarArchive.CreateArchive();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -139,26 +139,26 @@ public class ZipFactory
|
||||
#region IArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.Open(stream, readerOptions);
|
||||
public IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)Open(stream, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(Stream stream, ReaderOptions? readerOptions = null) =>
|
||||
(IAsyncArchive)OpenArchive(stream, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.Open(fileInfo, readerOptions);
|
||||
public IArchive OpenArchive(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.OpenArchive(fileInfo, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfo, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -166,28 +166,32 @@ public class ZipFactory
|
||||
#region IMultiArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<Stream> streams, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.Open(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)Open(streams, readerOptions);
|
||||
) => ZipArchive.OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IArchive Open(IReadOnlyList<FileInfo> fileInfos, ReaderOptions? readerOptions = null) =>
|
||||
ZipArchive.Open(fileInfos, readerOptions);
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<Stream> streams,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => (IAsyncArchive)OpenArchive(streams, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsync(
|
||||
public IArchive OpenArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => ZipArchive.OpenArchive(fileInfos, readerOptions);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncArchive OpenAsyncArchive(
|
||||
IReadOnlyList<FileInfo> fileInfos,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncArchive)Open(fileInfos, readerOptions);
|
||||
return (IAsyncArchive)OpenArchive(fileInfos, readerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -196,17 +200,17 @@ public class ZipFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReader OpenReader(Stream stream, ReaderOptions? options) =>
|
||||
ZipReader.Open(stream, options);
|
||||
ZipReader.OpenReader(stream, options);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncReader OpenReaderAsync(
|
||||
public IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)ZipReader.Open(stream, options);
|
||||
return (IAsyncReader)ZipReader.OpenReader(stream, options);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -214,18 +218,18 @@ public class ZipFactory
|
||||
#region IWriterFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWriter Open(Stream stream, WriterOptions writerOptions) =>
|
||||
public IWriter OpenWriter(Stream stream, WriterOptions writerOptions) =>
|
||||
new ZipWriter(stream, new ZipWriterOptions(writerOptions));
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAsyncWriter OpenAsync(
|
||||
public IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
WriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncWriter)Open(stream, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -233,7 +237,7 @@ public class ZipFactory
|
||||
#region IWriteableArchiveFactory
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IWritableArchive CreateWriteableArchive() => ZipArchive.Create();
|
||||
public IWritableArchive CreateArchive() => ZipArchive.CreateArchive();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ internal class BufferedSubStream : SharpCompressStream, IStreamStack
|
||||
|
||||
private int _cacheOffset;
|
||||
private int _cacheLength;
|
||||
private readonly byte[] _cache = ArrayPool<byte>.Shared.Rent(32 << 10);
|
||||
private readonly byte[] _cache = ArrayPool<byte>.Shared.Rent(32 << 10);
|
||||
private long origin;
|
||||
|
||||
private long BytesLeftToRead { get; set; }
|
||||
@@ -154,7 +154,7 @@ internal class BufferedSubStream : SharpCompressStream, IStreamStack
|
||||
return count;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -64,7 +64,7 @@ internal sealed class ProgressReportingStream : Stream
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
var bytesRead = _baseStream.Read(buffer);
|
||||
@@ -95,7 +95,7 @@ internal sealed class ProgressReportingStream : Stream
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -147,7 +147,7 @@ internal sealed class ProgressReportingStream : Stream
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
if (!_leaveOpen)
|
||||
|
||||
@@ -81,7 +81,7 @@ internal class ReadOnlySubStream : SharpCompressStream, IStreamStack
|
||||
return value;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override int Read(Span<byte> buffer)
|
||||
{
|
||||
var sliceLen = BytesLeftToRead < buffer.Length ? BytesLeftToRead : buffer.Length;
|
||||
@@ -117,7 +117,7 @@ internal class ReadOnlySubStream : SharpCompressStream, IStreamStack
|
||||
return read;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -384,7 +384,7 @@ public class SharpCompressStream : Stream, IStreamStack
|
||||
await Stream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
|
||||
@@ -98,6 +98,30 @@ public class SourceStream : Stream, IStreamStack
|
||||
|
||||
private Stream Current => _streams[_stream];
|
||||
|
||||
/// <summary>
|
||||
/// Creates an independent stream for the specified volume index.
|
||||
/// This allows multiple threads to read from different positions concurrently.
|
||||
/// Only works when IsFileMode is true.
|
||||
/// </summary>
|
||||
/// <param name="volumeIndex">The volume index to create a stream for</param>
|
||||
/// <returns>A new independent FileStream, or null if not in file mode or volume doesn't exist</returns>
|
||||
public Stream? CreateIndependentStream(int volumeIndex)
|
||||
{
|
||||
if (!IsFileMode)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure the volume is loaded
|
||||
if (!LoadStream(volumeIndex))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a new independent stream from the FileInfo
|
||||
return _files[volumeIndex].OpenRead();
|
||||
}
|
||||
|
||||
public bool LoadStream(int index) //ensure all parts to id are loaded
|
||||
{
|
||||
while (_streams.Count <= index)
|
||||
@@ -289,7 +313,7 @@ public class SourceStream : Stream, IStreamStack
|
||||
return total - count;
|
||||
}
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD2_0
|
||||
#if !LEGACY_DOTNET
|
||||
|
||||
public override async ValueTask<int> ReadAsync(
|
||||
Memory<byte> buffer,
|
||||
|
||||
@@ -21,7 +21,7 @@ internal static class NotNullExtensions
|
||||
return source.AsEnumerable();
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK || NETSTANDARD
|
||||
#if LEGACY_DOTNET
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T NotNull<T>(this T? obj, string? message = null)
|
||||
where T : class
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0
|
||||
#if LEGACY_DOTNET
|
||||
|
||||
namespace SharpCompress;
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IAsyncReader
|
||||
}
|
||||
}
|
||||
//don't know the size so we have to try to decompress to skip
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0
|
||||
#if LEGACY_DOTNET
|
||||
using var s = await OpenEntryStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
await s.SkipEntryAsync(cancellationToken).ConfigureAwait(false);
|
||||
#else
|
||||
@@ -344,7 +344,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IAsyncReader
|
||||
|
||||
internal async ValueTask WriteAsync(Stream writeStream, CancellationToken cancellationToken)
|
||||
{
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0
|
||||
#if LEGACY_DOTNET
|
||||
using Stream s = await OpenEntryStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
var sourceStream = WrapWithProgress(s, Entry);
|
||||
await sourceStream.CopyToAsync(writeStream, 81920, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Ace;
|
||||
|
||||
public partial class AceReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class AceReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace SharpCompress.Readers.Ace
|
||||
/// <param name="stream">The stream containing the ACE archive.</param>
|
||||
/// <param name="options">Reader options.</param>
|
||||
/// <returns>An AceReader instance.</returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new SingleVolumeAceReader(stream, options ?? new ReaderOptions());
|
||||
@@ -62,7 +62,7 @@ namespace SharpCompress.Readers.Ace
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeAceReader(streams, options ?? new ReaderOptions());
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Arc;
|
||||
|
||||
public partial class ArcReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class ArcReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SharpCompress.Readers.Arc
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new ArcReader(stream, options ?? new ReaderOptions());
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Arj;
|
||||
|
||||
public partial class ArjReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class ArjReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace SharpCompress.Readers.Arj
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new SingleVolumeArjReader(stream, options ?? new ReaderOptions());
|
||||
@@ -39,7 +39,7 @@ namespace SharpCompress.Readers.Arj
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeArjReader(streams, options ?? new ReaderOptions());
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.GZip;
|
||||
|
||||
public partial class GZipReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class GZipReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,7 @@ public partial class GZipReader : AbstractReader<GZipEntry, GZipVolume>
|
||||
|
||||
public override GZipVolume Volume { get; }
|
||||
|
||||
#region Open
|
||||
#region OpenReader
|
||||
|
||||
/// <summary>
|
||||
/// Opens a GZipReader for Non-seeking usage with a single volume
|
||||
@@ -20,13 +20,13 @@ public partial class GZipReader : AbstractReader<GZipEntry, GZipVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new GZipReader(stream, options ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
#endregion Open
|
||||
#endregion OpenReader
|
||||
|
||||
protected override IEnumerable<GZipEntry> GetEntries(Stream stream) =>
|
||||
GZipEntry.GetEntries(stream, Options);
|
||||
|
||||
@@ -6,13 +6,21 @@ namespace SharpCompress.Readers;
|
||||
public interface IReaderFactory : Factories.IFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Opens a Reader for Non-seeking usage
|
||||
/// Opens a Reader for Non-seeking usage.
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
IReader OpenReader(Stream stream, ReaderOptions? options);
|
||||
IAsyncReader OpenReaderAsync(
|
||||
|
||||
/// <summary>
|
||||
/// Opens a Reader for Non-seeking usage asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
CancellationToken cancellationToken
|
||||
|
||||
@@ -6,25 +6,28 @@ namespace SharpCompress.Readers;
|
||||
|
||||
public interface IReaderOpenable
|
||||
{
|
||||
public static abstract IReader Open(string filePath, ReaderOptions? readerOptions = null);
|
||||
public static abstract IReader OpenReader(string filePath, ReaderOptions? readerOptions = null);
|
||||
|
||||
public static abstract IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null);
|
||||
public static abstract IReader OpenReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null
|
||||
);
|
||||
|
||||
public static abstract IReader Open(Stream stream, ReaderOptions? readerOptions = null);
|
||||
public static abstract IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null);
|
||||
|
||||
public static abstract IAsyncReader OpenAsync(
|
||||
public static abstract IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract IAsyncReader OpenAsync(
|
||||
public static abstract IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract IAsyncReader OpenAsync(
|
||||
public static abstract IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Rar;
|
||||
|
||||
public partial class RarReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,27 +15,27 @@ public partial class RarReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,27 +40,27 @@ public abstract partial class RarReader : AbstractReader<RarReaderEntry, RarVolu
|
||||
|
||||
public override RarVolume? Volume => volume;
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), options);
|
||||
return OpenReader(new FileInfo(filePath), options);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfo.OpenRead(), options);
|
||||
return OpenReader(fileInfo.OpenRead(), options);
|
||||
}
|
||||
|
||||
public static IReader Open(IEnumerable<string> filePaths, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(IEnumerable<string> filePaths, ReaderOptions? options = null)
|
||||
{
|
||||
return Open(filePaths.Select(x => new FileInfo(x)), options);
|
||||
return OpenReader(filePaths.Select(x => new FileInfo(x)), options);
|
||||
}
|
||||
|
||||
public static IReader Open(IEnumerable<FileInfo> fileInfos, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(IEnumerable<FileInfo> fileInfos, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfos.Select(x => x.OpenRead()), options);
|
||||
return OpenReader(fileInfos.Select(x => x.OpenRead()), options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -69,7 +69,7 @@ public abstract partial class RarReader : AbstractReader<RarReaderEntry, RarVolu
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new SingleVolumeRarReader(stream, options ?? new ReaderOptions());
|
||||
@@ -81,7 +81,7 @@ public abstract partial class RarReader : AbstractReader<RarReaderEntry, RarVolu
|
||||
/// <param name="streams"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeRarReader(streams, options ?? new ReaderOptions());
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace SharpCompress.Readers;
|
||||
|
||||
public static class ReaderFactory
|
||||
{
|
||||
public static IReader Open(string filePath, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), options);
|
||||
return OpenReader(new FileInfo(filePath), options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -24,20 +24,20 @@ public static class ReaderFactory
|
||||
/// <param name="options"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string filePath,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return OpenAsync(new FileInfo(filePath), options, cancellationToken);
|
||||
return OpenAsyncReader(new FileInfo(filePath), options, cancellationToken);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfo.OpenRead(), options);
|
||||
return OpenReader(fileInfo.OpenRead(), options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,14 +47,14 @@ public static class ReaderFactory
|
||||
/// <param name="options"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return OpenAsync(fileInfo.OpenRead(), options, cancellationToken);
|
||||
return OpenAsyncReader(fileInfo.OpenRead(), options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -63,7 +63,7 @@ public static class ReaderFactory
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
options ??= new ReaderOptions() { LeaveStreamOpen = false };
|
||||
@@ -110,7 +110,7 @@ public static class ReaderFactory
|
||||
);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -139,7 +139,7 @@ public static class ReaderFactory
|
||||
if (testedFactory.IsArchive(bStream))
|
||||
{
|
||||
((IStreamStack)bStream).StackSeek(pos);
|
||||
return readerFactory.OpenReaderAsync(bStream, options, cancellationToken);
|
||||
return readerFactory.OpenAsyncReader(bStream, options, cancellationToken);
|
||||
}
|
||||
}
|
||||
((IStreamStack)bStream).StackSeek(pos);
|
||||
@@ -155,7 +155,7 @@ public static class ReaderFactory
|
||||
if (factory is IReaderFactory readerFactory && factory.IsArchive(bStream))
|
||||
{
|
||||
((IStreamStack)bStream).StackSeek(pos);
|
||||
return readerFactory.OpenReaderAsync(bStream, options, cancellationToken);
|
||||
return readerFactory.OpenAsyncReader(bStream, options, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,4 +28,12 @@ public class ReaderOptions : OptionsBase
|
||||
/// When set, progress updates will be reported as entries are extracted.
|
||||
/// </summary>
|
||||
public IProgress<ProgressReport>? Progress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable multi-threaded extraction support when the archive is opened from a FileInfo or file path.
|
||||
/// When enabled, multiple threads can extract different entries concurrently by creating
|
||||
/// independent file streams. This is only effective for archives opened from files, not streams.
|
||||
/// Default is false for backward compatibility.
|
||||
/// </summary>
|
||||
public bool EnableMultiThreadedExtraction { get; set; }
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Tar;
|
||||
|
||||
public partial class TarReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class TarReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@ public partial class TarReader : AbstractReader<TarEntry, TarVolume>
|
||||
};
|
||||
}
|
||||
|
||||
#region Open
|
||||
#region OpenReader
|
||||
|
||||
/// <summary>
|
||||
/// Opens a TarReader for Non-seeking usage with a single volume
|
||||
@@ -53,7 +53,7 @@ public partial class TarReader : AbstractReader<TarEntry, TarVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
options = options ?? new ReaderOptions();
|
||||
@@ -115,7 +115,7 @@ public partial class TarReader : AbstractReader<TarEntry, TarVolume>
|
||||
return new TarReader(rewindableStream, options, CompressionType.None);
|
||||
}
|
||||
|
||||
#endregion Open
|
||||
#endregion OpenReader
|
||||
|
||||
protected override IEnumerable<TarEntry> GetEntries(Stream stream) =>
|
||||
TarEntry.GetEntries(
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace SharpCompress.Readers.Zip;
|
||||
|
||||
public partial class ZipReader : IReaderOpenable
|
||||
{
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
string path,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -15,39 +15,39 @@ public partial class ZipReader : IReaderOpenable
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
path.NotNullOrEmpty(nameof(path));
|
||||
return (IAsyncReader)Open(new FileInfo(path), readerOptions);
|
||||
return (IAsyncReader)OpenReader(new FileInfo(path), readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
Stream stream,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(stream, readerOptions);
|
||||
return (IAsyncReader)OpenReader(stream, readerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncReader OpenAsync(
|
||||
public static IAsyncReader OpenAsyncReader(
|
||||
FileInfo fileInfo,
|
||||
ReaderOptions? readerOptions = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncReader)Open(fileInfo, readerOptions);
|
||||
return (IAsyncReader)OpenReader(fileInfo, readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(string filePath, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), readerOptions);
|
||||
return OpenReader(new FileInfo(filePath), readerOptions);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
public static IReader OpenReader(FileInfo fileInfo, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return Open(fileInfo.OpenRead(), readerOptions);
|
||||
return OpenReader(fileInfo.OpenRead(), readerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,13 +45,17 @@ public partial class ZipReader : AbstractReader<ZipEntry, ZipVolume>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IReader Open(Stream stream, ReaderOptions? options = null)
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new ZipReader(stream, options ?? new ReaderOptions());
|
||||
}
|
||||
|
||||
public static IReader Open(Stream stream, ReaderOptions? options, IEnumerable<ZipEntry> entries)
|
||||
public static IReader OpenReader(
|
||||
Stream stream,
|
||||
ReaderOptions? options,
|
||||
IEnumerable<ZipEntry> entries
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new ZipReader(stream, options ?? new ReaderOptions(), entries);
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net48' Or '$(TargetFramework)' == 'netstandard20' ">
|
||||
<DefineConstants>$(DefineConstants);LEGACY_DOTNET</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net10.0' ">
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -189,7 +189,7 @@ internal static class Utility
|
||||
}
|
||||
}
|
||||
|
||||
#if NET60_OR_GREATER
|
||||
#if NET8_0_OR_GREATER
|
||||
public bool ReadFully(byte[] buffer)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -7,52 +7,52 @@ namespace SharpCompress.Writers.GZip;
|
||||
|
||||
public partial class GZipWriter : IWriterOpenable<GZipWriterOptions>
|
||||
{
|
||||
public static IWriter Open(string filePath, GZipWriterOptions writerOptions)
|
||||
public static IWriter OpenWriter(string filePath, GZipWriterOptions writerOptions)
|
||||
{
|
||||
filePath.NotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), writerOptions);
|
||||
return OpenWriter(new FileInfo(filePath), writerOptions);
|
||||
}
|
||||
|
||||
public static IWriter Open(FileInfo fileInfo, GZipWriterOptions writerOptions)
|
||||
public static IWriter OpenWriter(FileInfo fileInfo, GZipWriterOptions writerOptions)
|
||||
{
|
||||
fileInfo.NotNull(nameof(fileInfo));
|
||||
return new GZipWriter(fileInfo.OpenWrite(), writerOptions);
|
||||
}
|
||||
|
||||
public static IWriter Open(Stream stream, GZipWriterOptions writerOptions)
|
||||
public static IWriter OpenWriter(Stream stream, GZipWriterOptions writerOptions)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
return new GZipWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncWriter OpenAsync(
|
||||
public static IAsyncWriter OpenAsyncWriter(
|
||||
string path,
|
||||
GZipWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncWriter)Open(path, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(path, writerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncWriter OpenAsync(
|
||||
public static IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
GZipWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncWriter)Open(stream, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
public static IAsyncWriter OpenAsync(
|
||||
public static IAsyncWriter OpenAsyncWriter(
|
||||
FileInfo fileInfo,
|
||||
GZipWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return (IAsyncWriter)Open(fileInfo, writerOptions);
|
||||
return (IAsyncWriter)OpenWriter(fileInfo, writerOptions);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace SharpCompress.Writers;
|
||||
|
||||
public interface IWriterFactory : IFactory
|
||||
{
|
||||
IWriter Open(Stream stream, WriterOptions writerOptions);
|
||||
IWriter OpenWriter(Stream stream, WriterOptions writerOptions);
|
||||
|
||||
IAsyncWriter OpenAsync(
|
||||
IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
WriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -7,10 +7,10 @@ namespace SharpCompress.Writers;
|
||||
public interface IWriterOpenable<TWriterOptions>
|
||||
where TWriterOptions : WriterOptions
|
||||
{
|
||||
public static abstract IWriter Open(string filePath, TWriterOptions writerOptions);
|
||||
public static abstract IWriter OpenWriter(string filePath, TWriterOptions writerOptions);
|
||||
|
||||
public static abstract IWriter Open(FileInfo fileInfo, TWriterOptions writerOptions);
|
||||
public static abstract IWriter Open(Stream stream, TWriterOptions writerOptions);
|
||||
public static abstract IWriter OpenWriter(FileInfo fileInfo, TWriterOptions writerOptions);
|
||||
public static abstract IWriter OpenWriter(Stream stream, TWriterOptions writerOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Opens a Writer asynchronously.
|
||||
@@ -20,19 +20,19 @@ public interface IWriterOpenable<TWriterOptions>
|
||||
/// <param name="writerOptions">Writer options.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>A task that returns an IWriter.</returns>
|
||||
public static abstract IAsyncWriter OpenAsync(
|
||||
public static abstract IAsyncWriter OpenAsyncWriter(
|
||||
Stream stream,
|
||||
TWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract IAsyncWriter OpenAsync(
|
||||
public static abstract IAsyncWriter OpenAsyncWriter(
|
||||
string filePath,
|
||||
TWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
public static abstract IAsyncWriter OpenAsync(
|
||||
public static abstract IAsyncWriter OpenAsyncWriter(
|
||||
FileInfo fileInfo,
|
||||
TWriterOptions writerOptions,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user