mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-13 20:46:47 +00:00
fix: Change LeaveStreamOpen default from true to false
As of v0.21, the library is documented to close wrapped streams by default. However, the ReaderOptions.LeaveStreamOpen property defaulted to true, which contradicted the documented behavior and caused file locks when deleting archives after extraction. Changes: - Set LeaveStreamOpen = false as the default (consistent with v0.21 design) - Updated ReaderOptions.cs with comprehensive documentation explaining: * File-based vs caller-provided stream handling * When to use LeaveStreamOpen = true * Usage examples for both scenarios - Updated AGENTS.md Stream Handling Rules section with: * Clear explanation of default disposal behavior * Overload differences (file-based vs stream-based) * Guidance on using ForExternalStream preset This ensures the implementation matches the documented behavior and prevents unexpected file locking issues during archive deletion. Fixes: File deletion failures after archive extraction
This commit is contained in:
11
AGENTS.md
11
AGENTS.md
@@ -126,10 +126,15 @@ SharpCompress supports multiple archive and compression formats:
|
||||
- See [docs/FORMATS.md](docs/FORMATS.md) for complete format support matrix
|
||||
|
||||
### Stream Handling Rules
|
||||
- **Disposal**: As of version 0.21, SharpCompress closes wrapped streams by default
|
||||
- Use `ReaderOptions` or `WriterOptions` with `LeaveStreamOpen = true` to control stream disposal
|
||||
- **Disposal**: As of version 0.21, SharpCompress **closes wrapped streams by default** (`LeaveStreamOpen = false`)
|
||||
- File-based overloads (e.g., `OpenArchive(string filePath)`) use `ReaderOptions.ForFilePath` automatically
|
||||
- Stream-based overloads (e.g., `OpenArchive(Stream stream)`) use `ReaderOptions.ForExternalStream` by default, which sets `LeaveStreamOpen = true`
|
||||
- **For caller-provided streams**: Use `ReaderOptions` with `LeaveStreamOpen = true` or the `ForExternalStream` preset to prevent automatic disposal
|
||||
- Example: `var options = new ReaderOptions { LeaveStreamOpen = true };`
|
||||
- Or: `var options = ReaderOptions.ForExternalStream;`
|
||||
- **For file paths**: SharpCompress manages the stream lifecycle; no manual disposal needed beyond the archive/reader itself
|
||||
- Use `NonDisposingStream` wrapper when working with compression streams directly to prevent disposal
|
||||
- Always dispose of readers, writers, and archives in `using` blocks
|
||||
- Always dispose of readers, writers, and archives in `using` / `await using` blocks
|
||||
- For forward-only operations, use Reader/Writer APIs; for random access, use Archive APIs
|
||||
|
||||
### Async/Await Patterns
|
||||
|
||||
@@ -24,9 +24,36 @@ namespace SharpCompress.Readers;
|
||||
public sealed record ReaderOptions : IReaderOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// SharpCompress will keep the supplied streams open. Default is true.
|
||||
/// SharpCompress will keep the supplied streams open.
|
||||
/// Default is false as of v0.21: streams are closed when the archive/reader is disposed.
|
||||
/// Set to true when passing caller-owned streams that should not be disposed.
|
||||
/// </summary>
|
||||
public bool LeaveStreamOpen { get; init; } = true;
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>Default behavior (LeaveStreamOpen = false):</b>
|
||||
/// When you open an archive from a file path (e.g., <c>GZipArchive.OpenArchive(filePath)</c>),
|
||||
/// SharpCompress manages the stream lifetime and closes it on Dispose.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Caller-provided streams (LeaveStreamOpen = true):</b>
|
||||
/// When you pass a stream you created (FileStream, MemoryStream, NetworkStream, etc.),
|
||||
/// set LeaveStreamOpen = true to prevent SharpCompress from disposing it.
|
||||
/// Use <see cref="ForExternalStream"/> preset for convenience.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Example:</b>
|
||||
/// <code>
|
||||
/// // File-based: stream managed by library
|
||||
/// using var archive = GZipArchive.OpenArchive(filePath); // LeaveStreamOpen = false
|
||||
///
|
||||
/// // Caller-provided stream: caller manages lifetime
|
||||
/// using var stream = File.OpenRead(filePath);
|
||||
/// var options = new ReaderOptions { LeaveStreamOpen = true };
|
||||
/// using var archive = GZipArchive.OpenArchive(stream, options);
|
||||
/// </code>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public bool LeaveStreamOpen { get; init; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Encoding to use for archive entry names.
|
||||
|
||||
Reference in New Issue
Block a user