-
Notifications
You must be signed in to change notification settings - Fork 510
Change and clean up options #1193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
cc6e410
some options
adamhathcock 5437d9f
Initial plan
Copilot 4084b34
Fix RAR extraction to preserve subdirectory structure
Copilot d5cab81
Address code review feedback: clarify file size comment
Copilot 2a40813
Complete fix for RAR extraction subdirectory issue
Copilot 29197f2
Update tests/SharpCompress.Test/Rar/RarArchiveTests.cs
adamhathcock c4a28e7
Update tests/SharpCompress.Test/Rar/RarArchiveAsyncTests.cs
adamhathcock 2e074e1
Merge remote-tracking branch 'origin/master' into adam/cleanup-options
adamhathcock 04dd177
first pass of removing extraction options (folded into reader options)
adamhathcock 84c49f1
more removal
adamhathcock 938692e
refactor how options for reading was done
adamhathcock cf0ad9b
Merge remote-tracking branch 'origin/copilot/fix-rar-extraction-issue…
adamhathcock e216315
mismerge
adamhathcock e3c3b50
Use nullability for time in arj
adamhathcock 399572d
use specific writer options for writing archives
adamhathcock 0dcfbf5
fix more usage of writers
adamhathcock 2e364ac
cleaned up writing and added more validation and tests
adamhathcock bd99c1a
more fluent interface for options
adamhathcock 34f4314
Fix test
adamhathcock File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -20,14 +20,18 @@ 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 | ||||||
| // With fluent options (preferred) | ||||||
| var options = ReaderOptions.ForEncryptedArchive("password") | ||||||
| .WithArchiveEncoding(new ArchiveEncoding { Default = Encoding.GetEncoding(932) }); | ||||||
| using (var archive = ZipArchive.OpenArchive("encrypted.zip", options)) | ||||||
|
|
||||||
| // Alternative: object initializer | ||||||
| var options2 = new ReaderOptions | ||||||
| { | ||||||
| Password = "password", | ||||||
| LeaveStreamOpen = true, | ||||||
| ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) } | ||||||
| }; | ||||||
| using (var archive = ZipArchive.OpenArchive("encrypted.zip", options)) | ||||||
| ``` | ||||||
|
|
||||||
| ### Creating Archives | ||||||
|
|
@@ -44,16 +48,21 @@ using (var archive = ZipArchive.CreateArchive()) | |||||
| using (var archive = TarArchive.CreateArchive()) | ||||||
| using (var archive = GZipArchive.CreateArchive()) | ||||||
|
|
||||||
| // With options | ||||||
| var options = new WriterOptions(CompressionType.Deflate) | ||||||
| { | ||||||
| CompressionLevel = 9, | ||||||
| LeaveStreamOpen = false | ||||||
| }; | ||||||
| // With fluent options (preferred) | ||||||
| var options = WriterOptions.ForZip() | ||||||
| .WithCompressionLevel(9) | ||||||
| .WithLeaveStreamOpen(false); | ||||||
| using (var archive = ZipArchive.CreateArchive()) | ||||||
| { | ||||||
| archive.SaveTo("output.zip", options); | ||||||
| } | ||||||
|
|
||||||
| // Alternative: constructor with object initializer | ||||||
| var options2 = new WriterOptions(CompressionType.Deflate) | ||||||
| { | ||||||
| CompressionLevel = 9, | ||||||
| LeaveStreamOpen = false | ||||||
| }; | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
@@ -72,16 +81,11 @@ using (var archive = ZipArchive.OpenArchive("file.zip")) | |||||
| var entry = archive.Entries.FirstOrDefault(e => e.Key == "file.txt"); | ||||||
|
|
||||||
| // Extract all | ||||||
| archive.WriteToDirectory(@"C:\output", new ExtractionOptions | ||||||
| { | ||||||
| ExtractFullPath = true, | ||||||
| Overwrite = true | ||||||
| }); | ||||||
| archive.WriteToDirectory(@"C:\output"); | ||||||
|
|
||||||
| // Extract single entry | ||||||
| var entry = archive.Entries.First(); | ||||||
| entry.WriteToFile(@"C:\output\file.txt"); | ||||||
| entry.WriteToFile(@"C:\output\file.txt", new ExtractionOptions { Overwrite = true }); | ||||||
|
|
||||||
| // Get entry stream | ||||||
| using (var stream = entry.OpenEntryStream()) | ||||||
|
|
@@ -95,7 +99,6 @@ using (var asyncArchive = await ZipArchive.OpenAsyncArchive("file.zip")) | |||||
| { | ||||||
| await asyncArchive.WriteToDirectoryAsync( | ||||||
| @"C:\output", | ||||||
| new ExtractionOptions { ExtractFullPath = true, Overwrite = true }, | ||||||
| cancellationToken: cancellationToken | ||||||
| ); | ||||||
| } | ||||||
|
|
@@ -187,7 +190,6 @@ using (var reader = await ReaderFactory.OpenAsyncReader(stream)) | |||||
| // Async extraction of all entries | ||||||
| await reader.WriteAllToDirectoryAsync( | ||||||
| @"C:\output", | ||||||
| new ExtractionOptions { ExtractFullPath = true, Overwrite = true }, | ||||||
| cancellationToken | ||||||
| ); | ||||||
| } | ||||||
|
|
@@ -229,43 +231,91 @@ using (var writer = WriterFactory.OpenWriter(stream, ArchiveType.Zip, Compressio | |||||
|
|
||||||
| ### ReaderOptions | ||||||
|
|
||||||
| Use factory presets and fluent helpers for common configurations: | ||||||
|
|
||||||
| ```csharp | ||||||
| var options = new ReaderOptions | ||||||
| { | ||||||
| Password = "password", // For encrypted archives | ||||||
| LeaveStreamOpen = true, // Don't close wrapped stream | ||||||
| ArchiveEncoding = new ArchiveEncoding // Custom character encoding | ||||||
| { | ||||||
| Default = Encoding.GetEncoding(932) | ||||||
| } | ||||||
| }; | ||||||
| // External stream with password and custom encoding | ||||||
| var options = ReaderOptions.ForExternalStream() | ||||||
| .WithPassword("password") | ||||||
| .WithArchiveEncoding(new ArchiveEncoding { Default = Encoding.GetEncoding(932) }); | ||||||
|
|
||||||
| using (var archive = ZipArchive.OpenArchive("file.zip", options)) | ||||||
| { | ||||||
| // ... | ||||||
| } | ||||||
|
|
||||||
| // Common presets | ||||||
| var safeOptions = ReaderOptions.SafeExtract; // No overwrite | ||||||
| var flatOptions = ReaderOptions.FlatExtract; // No directory structure | ||||||
|
|
||||||
| // Factory defaults: | ||||||
| // - file path / FileInfo overloads use LeaveStreamOpen = false | ||||||
| // - stream overloads use LeaveStreamOpen = true | ||||||
| ``` | ||||||
|
|
||||||
| Alternative: traditional object initializer: | ||||||
|
|
||||||
| ```csharp | ||||||
| var options = new ReaderOptions | ||||||
| { | ||||||
| Password = "password", | ||||||
| LeaveStreamOpen = true, | ||||||
| ArchiveEncoding = new ArchiveEncoding { Default = Encoding.GetEncoding(932) } | ||||||
| }; | ||||||
| ``` | ||||||
|
|
||||||
| ### WriterOptions | ||||||
|
|
||||||
| Factory methods provide a clean, discoverable way to create writer options: | ||||||
|
|
||||||
| ```csharp | ||||||
| // Factory methods for common archive types | ||||||
| var zipOptions = WriterOptions.ForZip() // ZIP with Deflate | ||||||
| .WithCompressionLevel(9) // 0-9 for Deflate | ||||||
| .WithLeaveStreamOpen(false); // Close stream when done | ||||||
|
|
||||||
| var tarOptions = WriterOptions.ForTar(CompressionType.GZip) // TAR with GZip | ||||||
| .WithLeaveStreamOpen(false); | ||||||
|
|
||||||
| var gzipOptions = WriterOptions.ForGZip() // GZip file | ||||||
| .WithCompressionLevel(6); | ||||||
|
|
||||||
| archive.SaveTo("output.zip", zipOptions); | ||||||
| ``` | ||||||
|
|
||||||
| Alternative: traditional constructor with object initializer: | ||||||
|
|
||||||
| ```csharp | ||||||
| var options = new WriterOptions(CompressionType.Deflate) | ||||||
| { | ||||||
| CompressionLevel = 9, // 0-9 for Deflate | ||||||
| LeaveStreamOpen = true, // Don't close stream | ||||||
| CompressionLevel = 9, | ||||||
| LeaveStreamOpen = true, | ||||||
| }; | ||||||
| archive.SaveTo("output.zip", options); | ||||||
| ``` | ||||||
|
|
||||||
| ### ExtractionOptions | ||||||
| ### Extraction behavior | ||||||
|
|
||||||
| ```csharp | ||||||
| var options = new ExtractionOptions | ||||||
| var options = new ReaderOptions | ||||||
| { | ||||||
| ExtractFullPath = true, // Recreate directory structure | ||||||
| Overwrite = true, // Overwrite existing files | ||||||
| PreserveFileTime = true // Keep original timestamps | ||||||
| }; | ||||||
| archive.WriteToDirectory(@"C:\output", options); | ||||||
|
|
||||||
| using (var archive = ZipArchive.OpenArchive("file.zip", options)) | ||||||
| { | ||||||
| archive.WriteToDirectory(@"C:\output"); | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### Options matrix | ||||||
|
|
||||||
| ```text | ||||||
| ReaderOptions: open-time behavior (password, encoding, stream ownership, extraction defaults) | ||||||
| WriterOptions: write-time behavior (compression type/level, encoding, stream ownership) | ||||||
| ZipWriterEntryOptions: per-entry ZIP overrides (compression, level, timestamps, comments, zip64) | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
@@ -317,13 +367,9 @@ ArchiveType.ZStandard | |||||
| try | ||||||
| { | ||||||
| using (var archive = ZipArchive.Open("archive.zip", | ||||||
| new ReaderOptions { Password = "password" })) | ||||||
| ReaderOptions.ForEncryptedArchive("password"))) | ||||||
| { | ||||||
| archive.WriteToDirectory(@"C:\output", new ExtractionOptions | ||||||
| { | ||||||
| ExtractFullPath = true, | ||||||
| Overwrite = true | ||||||
| }); | ||||||
| archive.WriteToDirectory(@"C:\output"); | ||||||
| } | ||||||
| } | ||||||
| catch (PasswordRequiredException) | ||||||
|
|
@@ -348,7 +394,7 @@ var progress = new Progress<ProgressReport>(report => | |||||
| Console.WriteLine($"Extracting {report.EntryPath}: {report.PercentComplete}%"); | ||||||
| }); | ||||||
|
|
||||||
| var options = new ReaderOptions { Progress = progress }; | ||||||
| var options = ReaderOptions.ForOwnedFile().WithProgress(progress); | ||||||
|
||||||
| var options = ReaderOptions.ForOwnedFile().WithProgress(progress); | |
| var options = ReaderOptions.ForOwnedFile.WithProgress(progress); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs use
ReaderOptions.ForExternalStream()here, butForExternalStreamis a property, not a method. Update the sample toReaderOptions.ForExternalStream(no parentheses) so it compiles.