From 5f3031db4a2cc91da3cdcac62afc4ddd0f959b53 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 12 Feb 2026 11:53:19 +0000 Subject: [PATCH 1/9] Open for writing should be async --- .../Archives/ArchiveFactory.Async.cs | 8 +++- .../Archives/IMultiArchiveFactory.cs | 15 ++++++-- src/SharpCompress/Factories/GZipFactory.cs | 31 +++++++++++---- src/SharpCompress/Factories/RarFactory.cs | 23 ++++++++--- .../Factories/SevenZipFactory.cs | 26 ++++++++++--- src/SharpCompress/Factories/TarFactory.cs | 31 +++++++++++---- src/SharpCompress/Factories/ZipFactory.cs | 31 +++++++++++---- src/SharpCompress/Utility.Async.cs | 38 +++++++++++++++++++ src/SharpCompress/Writers/IWriterFactory.cs | 3 +- src/SharpCompress/Writers/WriterFactory.cs | 21 +++++----- tests/SharpCompress.Test/ArchiveTests.cs | 4 +- tests/SharpCompress.Test/GZip/AsyncTests.cs | 2 +- .../GZip/GZipWriterAsyncTests.cs | 2 +- .../Tar/TarArchiveAsyncTests.cs | 4 +- tests/SharpCompress.Test/WriterTests.cs | 2 +- .../Zip/ZipMemoryArchiveWithCrcAsyncTests.cs | 14 +++++-- 16 files changed, 190 insertions(+), 65 deletions(-) diff --git a/src/SharpCompress/Archives/ArchiveFactory.Async.cs b/src/SharpCompress/Archives/ArchiveFactory.Async.cs index 4af94a57..04f009cb 100644 --- a/src/SharpCompress/Archives/ArchiveFactory.Async.cs +++ b/src/SharpCompress/Archives/ArchiveFactory.Async.cs @@ -77,7 +77,9 @@ public static partial class ArchiveFactory var factory = await FindFactoryAsync(fileInfo, cancellationToken) .ConfigureAwait(false); - return factory.OpenAsyncArchive(filesArray, options); + return await factory + .OpenAsyncArchive(filesArray, options, cancellationToken) + .ConfigureAwait(false); } public static async ValueTask OpenAsyncArchive( @@ -106,7 +108,9 @@ public static partial class ArchiveFactory var factory = await FindFactoryAsync(firstStream, cancellationToken) .ConfigureAwait(false); - return factory.OpenAsyncArchive(streamsArray, options); + return await factory + .OpenAsyncArchive(streamsArray, options, cancellationToken) + .ConfigureAwait(false); } public static ValueTask FindFactoryAsync( diff --git a/src/SharpCompress/Archives/IMultiArchiveFactory.cs b/src/SharpCompress/Archives/IMultiArchiveFactory.cs index 936222e6..3f9e0ec1 100644 --- a/src/SharpCompress/Archives/IMultiArchiveFactory.cs +++ b/src/SharpCompress/Archives/IMultiArchiveFactory.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Threading; +using System.Threading.Tasks; using SharpCompress.Factories; using SharpCompress.Readers; @@ -33,9 +34,12 @@ public interface IMultiArchiveFactory : IFactory /// /// /// reading options. - IAsyncArchive OpenAsyncArchive( + /// Cancellation token. + /// A containing the opened async archive. + ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default ); /// @@ -50,8 +54,11 @@ public interface IMultiArchiveFactory : IFactory /// /// /// reading options. - IAsyncArchive OpenAsyncArchive( + /// Cancellation token. + /// A containing the opened async archive. + ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default ); } diff --git a/src/SharpCompress/Factories/GZipFactory.cs b/src/SharpCompress/Factories/GZipFactory.cs index ab40438c..447e15f0 100644 --- a/src/SharpCompress/Factories/GZipFactory.cs +++ b/src/SharpCompress/Factories/GZipFactory.cs @@ -95,10 +95,17 @@ public class GZipFactory ) => GZipArchive.OpenArchive(streams, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(streams, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await GZipArchive + .OpenAsyncArchive(streams, readerOptions, cancellationToken) + .ConfigureAwait(false); + } /// public IArchive OpenArchive( @@ -107,10 +114,17 @@ public class GZipFactory ) => GZipArchive.OpenArchive(fileInfos, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(fileInfos, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await GZipArchive + .OpenAsyncArchive(fileInfos, readerOptions, cancellationToken) + .ConfigureAwait(false); + } #endregion @@ -187,14 +201,15 @@ public class GZipFactory } /// - public IAsyncWriter OpenAsyncWriter( + public ValueTask OpenAsyncWriter( Stream stream, IWriterOptions writerOptions, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - return (IAsyncWriter)OpenWriter(stream, writerOptions); + var writer = OpenWriter(stream, writerOptions); + return new((IAsyncWriter)writer); } #endregion diff --git a/src/SharpCompress/Factories/RarFactory.cs b/src/SharpCompress/Factories/RarFactory.cs index c81e54a7..615f7fb4 100644 --- a/src/SharpCompress/Factories/RarFactory.cs +++ b/src/SharpCompress/Factories/RarFactory.cs @@ -90,10 +90,17 @@ public class RarFactory : Factory, IArchiveFactory, IMultiArchiveFactory, IReade ) => RarArchive.OpenArchive(streams, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(streams, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await RarArchive + .OpenAsyncArchive(streams, readerOptions, cancellationToken) + .ConfigureAwait(false); + } /// public IArchive OpenArchive( @@ -102,12 +109,16 @@ public class RarFactory : Factory, IArchiveFactory, IMultiArchiveFactory, IReade ) => RarArchive.OpenArchive(fileInfos, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default ) { - return (IAsyncArchive)OpenArchive(fileInfos, readerOptions); + cancellationToken.ThrowIfCancellationRequested(); + return await RarArchive + .OpenAsyncArchive(fileInfos, readerOptions, cancellationToken) + .ConfigureAwait(false); } #endregion diff --git a/src/SharpCompress/Factories/SevenZipFactory.cs b/src/SharpCompress/Factories/SevenZipFactory.cs index 93826468..e4942041 100644 --- a/src/SharpCompress/Factories/SevenZipFactory.cs +++ b/src/SharpCompress/Factories/SevenZipFactory.cs @@ -85,10 +85,17 @@ public class SevenZipFactory : Factory, IArchiveFactory, IMultiArchiveFactory ) => SevenZipArchive.OpenArchive(streams, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(streams, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await SevenZipArchive + .OpenAsyncArchive(streams, readerOptions, cancellationToken) + .ConfigureAwait(false); + } /// public IArchive OpenArchive( @@ -97,10 +104,17 @@ public class SevenZipFactory : Factory, IArchiveFactory, IMultiArchiveFactory ) => SevenZipArchive.OpenArchive(fileInfos, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(fileInfos, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await SevenZipArchive + .OpenAsyncArchive(fileInfos, readerOptions, cancellationToken) + .ConfigureAwait(false); + } #endregion diff --git a/src/SharpCompress/Factories/TarFactory.cs b/src/SharpCompress/Factories/TarFactory.cs index fd2f528f..00ba6be2 100644 --- a/src/SharpCompress/Factories/TarFactory.cs +++ b/src/SharpCompress/Factories/TarFactory.cs @@ -195,10 +195,17 @@ public class TarFactory ) => TarArchive.OpenArchive(streams, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(streams, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await TarArchive + .OpenAsyncArchive(streams, readerOptions, cancellationToken) + .ConfigureAwait(false); + } /// public IArchive OpenArchive( @@ -207,10 +214,17 @@ public class TarFactory ) => TarArchive.OpenArchive(fileInfos, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(fileInfos, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await TarArchive + .OpenAsyncArchive(fileInfos, readerOptions, cancellationToken) + .ConfigureAwait(false); + } #endregion @@ -298,14 +312,15 @@ public class TarFactory } /// - public IAsyncWriter OpenAsyncWriter( + public ValueTask OpenAsyncWriter( Stream stream, IWriterOptions writerOptions, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - return (IAsyncWriter)OpenWriter(stream, writerOptions); + var writer = OpenWriter(stream, writerOptions); + return new((IAsyncWriter)writer); } #endregion diff --git a/src/SharpCompress/Factories/ZipFactory.cs b/src/SharpCompress/Factories/ZipFactory.cs index 6c683a38..057bfb65 100644 --- a/src/SharpCompress/Factories/ZipFactory.cs +++ b/src/SharpCompress/Factories/ZipFactory.cs @@ -163,10 +163,17 @@ public class ZipFactory ) => ZipArchive.OpenArchive(streams, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList streams, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(streams, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await ZipArchive + .OpenAsyncArchive(streams, readerOptions, cancellationToken) + .ConfigureAwait(false); + } /// public IArchive OpenArchive( @@ -175,10 +182,17 @@ public class ZipFactory ) => ZipArchive.OpenArchive(fileInfos, readerOptions); /// - public IAsyncArchive OpenAsyncArchive( + public async ValueTask OpenAsyncArchive( IReadOnlyList fileInfos, - ReaderOptions? readerOptions = null - ) => (IAsyncArchive)OpenArchive(fileInfos, readerOptions); + ReaderOptions? readerOptions = null, + CancellationToken cancellationToken = default + ) + { + cancellationToken.ThrowIfCancellationRequested(); + return await ZipArchive + .OpenAsyncArchive(fileInfos, readerOptions, cancellationToken) + .ConfigureAwait(false); + } #endregion @@ -219,14 +233,15 @@ public class ZipFactory } /// - public IAsyncWriter OpenAsyncWriter( + public ValueTask OpenAsyncWriter( Stream stream, IWriterOptions writerOptions, CancellationToken cancellationToken = default ) { cancellationToken.ThrowIfCancellationRequested(); - return (IAsyncWriter)OpenWriter(stream, writerOptions); + var writer = OpenWriter(stream, writerOptions); + return new((IAsyncWriter)writer); } #endregion diff --git a/src/SharpCompress/Utility.Async.cs b/src/SharpCompress/Utility.Async.cs index e8e6b0c3..bc90ac96 100644 --- a/src/SharpCompress/Utility.Async.cs +++ b/src/SharpCompress/Utility.Async.cs @@ -119,4 +119,42 @@ internal static partial class Utility return (total >= count); } } + + /// + /// Opens a file stream for asynchronous writing. + /// Uses File.OpenHandle with FileOptions.Asynchronous on .NET 8.0+ for optimal performance. + /// Falls back to FileStream constructor with async options on legacy frameworks. + /// + /// The file path to open. + /// Cancellation token. + /// A FileStream configured for asynchronous operations. + public static Stream OpenAsyncWriteStream( + string path, + CancellationToken cancellationToken + ) + { + cancellationToken.ThrowIfCancellationRequested(); + +#if !LEGACY_DOTNET + // Use File.OpenHandle with async options for .NET 8.0+ + var handle = File.OpenHandle( + path, + FileMode.Create, + FileAccess.Write, + FileShare.None, + FileOptions.Asynchronous + ); + return new FileStream(handle, FileAccess.Write); +#else + // For legacy .NET, use FileStream constructor with async options + return new FileStream( + path, + FileMode.Create, + FileAccess.Write, + FileShare.None, + bufferSize: 4096, + FileOptions.Asynchronous + ); +#endif + } } diff --git a/src/SharpCompress/Writers/IWriterFactory.cs b/src/SharpCompress/Writers/IWriterFactory.cs index fc2ef301..c9eef005 100644 --- a/src/SharpCompress/Writers/IWriterFactory.cs +++ b/src/SharpCompress/Writers/IWriterFactory.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common.Options; using SharpCompress.Factories; @@ -9,7 +10,7 @@ public interface IWriterFactory : IFactory { IWriter OpenWriter(Stream stream, IWriterOptions writerOptions); - IAsyncWriter OpenAsyncWriter( + ValueTask OpenAsyncWriter( Stream stream, IWriterOptions writerOptions, CancellationToken cancellationToken = default diff --git a/src/SharpCompress/Writers/WriterFactory.cs b/src/SharpCompress/Writers/WriterFactory.cs index 1d392797..f923df51 100644 --- a/src/SharpCompress/Writers/WriterFactory.cs +++ b/src/SharpCompress/Writers/WriterFactory.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using SharpCompress.Common; using SharpCompress.Common.Options; @@ -29,7 +30,7 @@ public static class WriterFactory return OpenWriter(fileInfo.OpenWrite(), archiveType, writerOptions); } - public static IAsyncWriter OpenAsyncWriter( + public static async ValueTask OpenAsyncWriter( string filePath, ArchiveType archiveType, IWriterOptions writerOptions, @@ -37,7 +38,7 @@ public static class WriterFactory ) { filePath.NotNullOrEmpty(nameof(filePath)); - return OpenAsyncWriter( + return await OpenAsyncWriter( new FileInfo(filePath), archiveType, writerOptions, @@ -45,7 +46,7 @@ public static class WriterFactory ); } - public static IAsyncWriter OpenAsyncWriter( + public static async ValueTask OpenAsyncWriter( FileInfo fileInfo, ArchiveType archiveType, IWriterOptions writerOptions, @@ -53,12 +54,8 @@ public static class WriterFactory ) { fileInfo.NotNull(nameof(fileInfo)); - return OpenAsyncWriter( - fileInfo.Open(FileMode.Create, FileAccess.Write), - archiveType, - writerOptions, - cancellationToken - ); + var stream = Utility.OpenAsyncWriteStream(fileInfo.FullName, cancellationToken); + return await OpenAsyncWriter(stream, archiveType, writerOptions, cancellationToken); } public static IWriter OpenWriter( @@ -86,8 +83,8 @@ public static class WriterFactory /// The archive type. /// Writer options. /// Cancellation token. - /// A task that returns an IWriter. - public static IAsyncWriter OpenAsyncWriter( + /// A containing the async writer. + public static async ValueTask OpenAsyncWriter( Stream stream, ArchiveType archiveType, IWriterOptions writerOptions, @@ -100,7 +97,7 @@ public static class WriterFactory if (factory != null) { - return factory.OpenAsyncWriter(stream, writerOptions, cancellationToken); + return await factory.OpenAsyncWriter(stream, writerOptions, cancellationToken); } throw new NotSupportedException("Archive Type does not have a Writer: " + archiveType); diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs index 0d98e805..270900b9 100644 --- a/tests/SharpCompress.Test/ArchiveTests.cs +++ b/tests/SharpCompress.Test/ArchiveTests.cs @@ -383,7 +383,7 @@ public class ArchiveTests : ReaderTests return WriterFactory.OpenWriter(stream, ArchiveType.Zip, writerOptions); } - protected static IAsyncWriter CreateWriterWithLevelAsync( + protected static async ValueTask CreateWriterWithLevelAsync( Stream stream, CompressionType compressionType, int? compressionLevel = null @@ -392,7 +392,7 @@ public class ArchiveTests : ReaderTests var writerOptions = compressionLevel.HasValue ? new WriterOptions(compressionType, compressionLevel.Value) { LeaveStreamOpen = true } : new WriterOptions(compressionType) { LeaveStreamOpen = true }; - return WriterFactory.OpenAsyncWriter( + return await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(stream), ArchiveType.Zip, writerOptions diff --git a/tests/SharpCompress.Test/GZip/AsyncTests.cs b/tests/SharpCompress.Test/GZip/AsyncTests.cs index 8c0d19e1..cf334ef9 100644 --- a/tests/SharpCompress.Test/GZip/AsyncTests.cs +++ b/tests/SharpCompress.Test/GZip/AsyncTests.cs @@ -104,7 +104,7 @@ public class AsyncTests : TestBase await using (var stream = File.Create(outputPath)) #endif using ( - var writer = WriterFactory.OpenAsyncWriter( + var writer = await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(stream), ArchiveType.Zip, new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = false } diff --git a/tests/SharpCompress.Test/GZip/GZipWriterAsyncTests.cs b/tests/SharpCompress.Test/GZip/GZipWriterAsyncTests.cs index 60e115c0..a5d81899 100644 --- a/tests/SharpCompress.Test/GZip/GZipWriterAsyncTests.cs +++ b/tests/SharpCompress.Test/GZip/GZipWriterAsyncTests.cs @@ -24,7 +24,7 @@ public class GZipWriterAsyncTests : WriterTests ) ) using ( - var writer = WriterFactory.OpenAsyncWriter( + var writer = await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(stream), ArchiveType.GZip, new WriterOptions(CompressionType.GZip) diff --git a/tests/SharpCompress.Test/Tar/TarArchiveAsyncTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveAsyncTests.cs index 194a07d8..84d8ca40 100644 --- a/tests/SharpCompress.Test/Tar/TarArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/Tar/TarArchiveAsyncTests.cs @@ -35,7 +35,7 @@ public class TarArchiveAsyncTests : ArchiveTests using (Stream stream = File.OpenWrite(Path.Combine(SCRATCH2_FILES_PATH, archive))) { using ( - var writer = WriterFactory.OpenAsyncWriter( + var writer = await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(stream), ArchiveType.Tar, new WriterOptions(CompressionType.None) { LeaveStreamOpen = false } @@ -94,7 +94,7 @@ public class TarArchiveAsyncTests : ArchiveTests // Step 1: create a tar file containing a file with a long name using (Stream stream = File.OpenWrite(Path.Combine(SCRATCH2_FILES_PATH, archive))) using ( - var writer = WriterFactory.OpenAsyncWriter( + var writer = await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(stream), ArchiveType.Tar, new WriterOptions(CompressionType.None) { LeaveStreamOpen = false } diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs index 786cc41d..5fc18c6c 100644 --- a/tests/SharpCompress.Test/WriterTests.cs +++ b/tests/SharpCompress.Test/WriterTests.cs @@ -70,7 +70,7 @@ public class WriterTests : TestBase writerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default; - using var writer = WriterFactory.OpenAsyncWriter(stream, _type, writerOptions); + using var writer = await WriterFactory.OpenAsyncWriter(stream, _type, writerOptions); await writer.WriteAllAsync( ORIGINAL_FILES_PATH, "*", diff --git a/tests/SharpCompress.Test/Zip/ZipMemoryArchiveWithCrcAsyncTests.cs b/tests/SharpCompress.Test/Zip/ZipMemoryArchiveWithCrcAsyncTests.cs index c57d5026..52a0d98d 100644 --- a/tests/SharpCompress.Test/Zip/ZipMemoryArchiveWithCrcAsyncTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipMemoryArchiveWithCrcAsyncTests.cs @@ -62,7 +62,11 @@ public class ZipTypesLevelsWithCrcRatioAsyncTests : ArchiveTests // Create zip archive in memory using var zipStream = new MemoryStream(); using ( - var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel) + var writer = await CreateWriterWithLevelAsync( + zipStream, + compressionType, + compressionLevel + ) ) { await writer.WriteAsync($"file1_{sizeMb}MiB.txt", new MemoryStream(file1Data)); @@ -133,7 +137,7 @@ public class ZipTypesLevelsWithCrcRatioAsyncTests : ArchiveTests }; using ( - var writer = WriterFactory.OpenAsyncWriter( + var writer = await WriterFactory.OpenAsyncWriter( new AsyncOnlyStream(zipStream), ArchiveType.Zip, writerOptions @@ -201,7 +205,11 @@ public class ZipTypesLevelsWithCrcRatioAsyncTests : ArchiveTests // Create archive with specified compression and level using var zipStream = new MemoryStream(); using ( - var writer = CreateWriterWithLevelAsync(zipStream, compressionType, compressionLevel) + var writer = await CreateWriterWithLevelAsync( + zipStream, + compressionType, + compressionLevel + ) ) { await writer.WriteAsync( From 92c04a9ba46677e13d97978b7675e1ee8118b4c7 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 12 Feb 2026 11:59:11 +0000 Subject: [PATCH 2/9] don't leave created streams open --- src/SharpCompress/Writers/WriterFactory.cs | 13 ++++++++-- .../Writers/WriterOptionsExtensions.cs | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/SharpCompress/Writers/WriterFactory.cs b/src/SharpCompress/Writers/WriterFactory.cs index f923df51..43d46b3b 100644 --- a/src/SharpCompress/Writers/WriterFactory.cs +++ b/src/SharpCompress/Writers/WriterFactory.cs @@ -27,7 +27,11 @@ public static class WriterFactory ) { fileInfo.NotNull(nameof(fileInfo)); - return OpenWriter(fileInfo.OpenWrite(), archiveType, writerOptions); + return OpenWriter( + fileInfo.OpenWrite(), + archiveType, + writerOptions.WithLeaveStreamOpen(false) + ); } public static async ValueTask OpenAsyncWriter( @@ -55,7 +59,12 @@ public static class WriterFactory { fileInfo.NotNull(nameof(fileInfo)); var stream = Utility.OpenAsyncWriteStream(fileInfo.FullName, cancellationToken); - return await OpenAsyncWriter(stream, archiveType, writerOptions, cancellationToken); + return await OpenAsyncWriter( + stream, + archiveType, + writerOptions.WithLeaveStreamOpen(false), + cancellationToken + ); } public static IWriter OpenWriter( diff --git a/src/SharpCompress/Writers/WriterOptionsExtensions.cs b/src/SharpCompress/Writers/WriterOptionsExtensions.cs index d86b5406..0c3fb15e 100644 --- a/src/SharpCompress/Writers/WriterOptionsExtensions.cs +++ b/src/SharpCompress/Writers/WriterOptionsExtensions.cs @@ -1,6 +1,9 @@ using System; using SharpCompress.Common; using SharpCompress.Common.Options; +using SharpCompress.Writers.GZip; +using SharpCompress.Writers.Tar; +using SharpCompress.Writers.Zip; namespace SharpCompress.Writers; @@ -20,6 +23,29 @@ public static class WriterOptionsExtensions bool leaveStreamOpen ) => options with { LeaveStreamOpen = leaveStreamOpen }; + /// + /// Creates a copy with the specified LeaveStreamOpen value. + /// Works with any IWriterOptions implementation. + /// + /// The source options. + /// Whether to leave the stream open. + /// A new options instance with the specified LeaveStreamOpen value. + public static IWriterOptions WithLeaveStreamOpen( + this IWriterOptions options, + bool leaveStreamOpen + ) => + options switch + { + WriterOptions writerOptions => writerOptions with { LeaveStreamOpen = leaveStreamOpen }, + ZipWriterOptions zipOptions => zipOptions with { LeaveStreamOpen = leaveStreamOpen }, + TarWriterOptions tarOptions => tarOptions with { LeaveStreamOpen = leaveStreamOpen }, + GZipWriterOptions gzipOptions => gzipOptions with { LeaveStreamOpen = leaveStreamOpen }, + _ => throw new NotSupportedException( + $"Cannot set LeaveStreamOpen on options of type {options.GetType().Name}. " + + "Options must be a record type implementing IWriterOptions." + ), + }; + /// /// Creates a copy with the specified compression level. /// From 2dfe535e0b550881e0020f1276349ff218b0ac74 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 12 Feb 2026 12:10:43 +0000 Subject: [PATCH 3/9] add async read and write for files --- .../Readers/ReaderFactory.Async.cs | 5 +- .../Readers/Tar/TarReader.Factory.cs | 5 +- src/SharpCompress/Utility.Async.cs | 69 +++++++++++++++++++ src/SharpCompress/Writers/WriterFactory.cs | 2 +- 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/SharpCompress/Readers/ReaderFactory.Async.cs b/src/SharpCompress/Readers/ReaderFactory.Async.cs index c74a7133..f14a5f11 100644 --- a/src/SharpCompress/Readers/ReaderFactory.Async.cs +++ b/src/SharpCompress/Readers/ReaderFactory.Async.cs @@ -35,14 +35,15 @@ public static partial class ReaderFactory /// /// /// - public static ValueTask OpenAsyncReader( + public static async ValueTask OpenAsyncReader( FileInfo fileInfo, ReaderOptions? options = null, CancellationToken cancellationToken = default ) { options ??= ReaderOptions.ForOwnedFile; - return OpenAsyncReader(fileInfo.OpenRead(), options, cancellationToken); + var stream = fileInfo.OpenAsyncReadStream(cancellationToken); + return await OpenAsyncReader(stream, options, cancellationToken); } public static async ValueTask OpenAsyncReader( diff --git a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs index fc775d71..ba60296b 100644 --- a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs +++ b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs @@ -121,14 +121,15 @@ public partial class TarReader return new TarReader(sharpCompressStream, options, CompressionType.None); } - public static ValueTask OpenAsyncReader( + public static async ValueTask OpenAsyncReader( FileInfo fileInfo, ReaderOptions? readerOptions = null, CancellationToken cancellationToken = default ) { readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false }; - return OpenAsyncReader(fileInfo.OpenRead(), readerOptions, cancellationToken); + var stream = fileInfo.OpenAsyncReadStream(cancellationToken); + return await OpenAsyncReader(stream, readerOptions, cancellationToken); } public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null) diff --git a/src/SharpCompress/Utility.Async.cs b/src/SharpCompress/Utility.Async.cs index bc90ac96..564feb14 100644 --- a/src/SharpCompress/Utility.Async.cs +++ b/src/SharpCompress/Utility.Async.cs @@ -152,9 +152,78 @@ internal static partial class Utility FileMode.Create, FileAccess.Write, FileShare.None, + bufferSize: 4096, //default + FileOptions.Asynchronous + ); +#endif + } + + /// + /// Opens a file stream for asynchronous writing from a FileInfo. + /// Uses File.OpenHandle with FileOptions.Asynchronous on .NET 8.0+ for optimal performance. + /// Falls back to FileStream constructor with async options on legacy frameworks. + /// + /// The FileInfo to open. + /// Cancellation token. + /// A FileStream configured for asynchronous operations. + public static Stream OpenAsyncWriteStream( + this FileInfo fileInfo, + CancellationToken cancellationToken + ) + { + fileInfo.NotNull(nameof(fileInfo)); + return OpenAsyncWriteStream(fileInfo.FullName, cancellationToken); + } + + /// + /// Opens a file stream for asynchronous reading. + /// Uses File.OpenHandle with FileOptions.Asynchronous on .NET 8.0+ for optimal performance. + /// Falls back to FileStream constructor with async options on legacy frameworks. + /// + /// The file path to open. + /// Cancellation token. + /// A FileStream configured for asynchronous operations. + public static Stream OpenAsyncReadStream(string path, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + +#if !LEGACY_DOTNET + // Use File.OpenHandle with async options for .NET 8.0+ + var handle = File.OpenHandle( + path, + FileMode.Open, + FileAccess.Read, + FileShare.Read, + FileOptions.Asynchronous + ); + return new FileStream(handle, FileAccess.Read); +#else + // For legacy .NET, use FileStream constructor with async options + return new FileStream( + path, + FileMode.Open, + FileAccess.Read, + FileShare.Read, bufferSize: 4096, FileOptions.Asynchronous ); #endif } + + /// + /// Opens a file stream for asynchronous reading from a FileInfo. + /// Uses File.OpenHandle with FileOptions.Asynchronous on .NET 8.0+ for optimal performance. + /// Falls back to FileStream constructor with async options on legacy frameworks. + /// + /// The FileInfo to open. + /// Cancellation token. + /// A FileStream configured for asynchronous operations. + public static Stream OpenAsyncReadStream( + this FileInfo fileInfo, + CancellationToken cancellationToken + ) + { + fileInfo.NotNull(nameof(fileInfo)); + return OpenAsyncReadStream(fileInfo.FullName, cancellationToken); + } } diff --git a/src/SharpCompress/Writers/WriterFactory.cs b/src/SharpCompress/Writers/WriterFactory.cs index 43d46b3b..29ff3eed 100644 --- a/src/SharpCompress/Writers/WriterFactory.cs +++ b/src/SharpCompress/Writers/WriterFactory.cs @@ -58,7 +58,7 @@ public static class WriterFactory ) { fileInfo.NotNull(nameof(fileInfo)); - var stream = Utility.OpenAsyncWriteStream(fileInfo.FullName, cancellationToken); + var stream = fileInfo.OpenAsyncWriteStream(cancellationToken); return await OpenAsyncWriter( stream, archiveType, From b5bd4cbf53e88542518fd3f3c531b78d85f10975 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 12 Feb 2026 12:15:00 +0000 Subject: [PATCH 4/9] fmt --- src/SharpCompress/Utility.Async.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/SharpCompress/Utility.Async.cs b/src/SharpCompress/Utility.Async.cs index 564feb14..26d08ff7 100644 --- a/src/SharpCompress/Utility.Async.cs +++ b/src/SharpCompress/Utility.Async.cs @@ -128,10 +128,7 @@ internal static partial class Utility /// The file path to open. /// Cancellation token. /// A FileStream configured for asynchronous operations. - public static Stream OpenAsyncWriteStream( - string path, - CancellationToken cancellationToken - ) + public static Stream OpenAsyncWriteStream(string path, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); From 158460bc77593ec32423ba7d64aaeaeedea30a1e Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 12 Feb 2026 13:22:13 +0000 Subject: [PATCH 5/9] fix benchmarks --- tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs | 2 +- tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs index 521e7438..921d3282 100644 --- a/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs @@ -122,7 +122,7 @@ public class TarBenchmarks : ArchiveBenchmarkBase public async Task TarCreateSmallFilesAsync() { using var outputStream = new MemoryStream(); - await using var writer = WriterFactory.OpenAsyncWriter( + await using var writer = await WriterFactory.OpenAsyncWriter( outputStream, ArchiveType.Tar, new WriterOptions(CompressionType.None) { LeaveStreamOpen = true } diff --git a/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs index 375c5690..c848ab45 100644 --- a/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs @@ -98,7 +98,7 @@ public class ZipBenchmarks : ArchiveBenchmarkBase public async Task ZipCreateSmallFilesAsync() { using var outputStream = new MemoryStream(); - await using var writer = WriterFactory.OpenAsyncWriter( + await using var writer = await WriterFactory.OpenAsyncWriter( outputStream, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = true } From c5200c299ccc25ea78054e5b234a3be1fa65b056 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 17 Feb 2026 13:32:34 +0000 Subject: [PATCH 6/9] Downgrade dependencies for legacy frameworks --- Directory.Packages.props | 6 +- src/SharpCompress/SharpCompress.csproj | 2 - src/SharpCompress/packages.lock.json | 134 +++++++++----------- tests/SharpCompress.Test/packages.lock.json | 113 ++++++++++------- 4 files changed, 131 insertions(+), 124 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 8f8510d9..28b67540 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,13 +5,11 @@ - + - - - + diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index d3ccd21d..797c7378 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -38,8 +38,6 @@ - - diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index 27e9e496..341de67f 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -4,11 +4,11 @@ ".NETFramework,Version=v4.8": { "Microsoft.Bcl.AsyncInterfaces": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "vFuwSLj9QJBbNR0NeNO4YVASUbokxs+i/xbuu8B+Fs4FAZg5QaFa6eGrMaRqTzzNI5tAb97T7BhSxtLckFyiRA==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { - "System.Threading.Tasks.Extensions": "4.6.3" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Microsoft.NETFramework.ReferenceAssemblies": { @@ -36,32 +36,14 @@ "resolved": "17.14.15", "contentHash": "mXQPJsbuUD2ydq4/ffd8h8tSOFCXec+2xJOVNCvXjuMOq/+5EKHq3D2m2MC2+nUaXeFMSt66VS/J4HdKBixgcw==" }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.1, )", - "resolved": "4.6.1", - "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" - }, - "System.Memory": { - "type": "Direct", - "requested": "[4.6.3, )", - "resolved": "4.6.3", - "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", - "dependencies": { - "System.Buffers": "4.6.1", - "System.Numerics.Vectors": "4.6.1", - "System.Runtime.CompilerServices.Unsafe": "6.1.2" - } - }, "System.Text.Encoding.CodePages": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "QLP54mIATaBpjGlsZIxga38VPk1G9js0Kw651B+bvrXi2kSgGZYrxJSpM3whhTZCBK4HEBHX3fzfDQMw7CXHGQ==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", "dependencies": { - "System.Memory": "4.6.3", - "System.Runtime.CompilerServices.Unsafe": "6.1.2", - "System.ValueTuple": "4.6.1" + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Microsoft.Build.Tasks.Git": { @@ -79,38 +61,48 @@ "resolved": "10.0.102", "contentHash": "Mk1IMb9q5tahC2NltxYXFkLBtuBvfBoCQ3pIxYQWfzbCE9o1OB9SsHe0hnNGo7lWgTA/ePbFAJLWu6nLL9K17A==" }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.6.1", - "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.1.2", - "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", - "resolved": "4.6.3", - "contentHash": "7sCiwilJLYbTZELaKnc7RecBBXWXA+xMLQWZKWawBxYjp6DBlSE3v9/UcvKBvr1vv2tTOhipiogM8rRmxlhrVA==", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Runtime.CompilerServices.Unsafe": "4.5.3" } - }, - "System.ValueTuple": { - "type": "Transitive", - "resolved": "4.6.1", - "contentHash": "+RJT4qaekpZ7DDLhf+LTjq+E48jieKiY9ulJ+BoxKmZblIJfIJT8Ufcaa/clQqnYvWs8jugfGSMu8ylS0caG0w==" } }, ".NETStandard,Version=v2.0": { "Microsoft.Bcl.AsyncInterfaces": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "vFuwSLj9QJBbNR0NeNO4YVASUbokxs+i/xbuu8B+Fs4FAZg5QaFa6eGrMaRqTzzNI5tAb97T7BhSxtLckFyiRA==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { - "System.Threading.Tasks.Extensions": "4.6.3" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "Microsoft.NETFramework.ReferenceAssemblies": { @@ -147,31 +139,14 @@ "Microsoft.NETCore.Platforms": "1.1.0" } }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.1, )", - "resolved": "4.6.1", - "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" - }, - "System.Memory": { - "type": "Direct", - "requested": "[4.6.3, )", - "resolved": "4.6.3", - "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", - "dependencies": { - "System.Buffers": "4.6.1", - "System.Numerics.Vectors": "4.6.1", - "System.Runtime.CompilerServices.Unsafe": "6.1.2" - } - }, "System.Text.Encoding.CodePages": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "QLP54mIATaBpjGlsZIxga38VPk1G9js0Kw651B+bvrXi2kSgGZYrxJSpM3whhTZCBK4HEBHX3fzfDQMw7CXHGQ==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", "dependencies": { - "System.Memory": "4.6.3", - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Microsoft.Build.Tasks.Git": { @@ -194,22 +169,37 @@ "resolved": "10.0.102", "contentHash": "Mk1IMb9q5tahC2NltxYXFkLBtuBvfBoCQ3pIxYQWfzbCE9o1OB9SsHe0hnNGo7lWgTA/ePbFAJLWu6nLL9K17A==" }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.6.1", - "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.1.2", - "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Threading.Tasks.Extensions": { "type": "Transitive", - "resolved": "4.6.3", - "contentHash": "7sCiwilJLYbTZELaKnc7RecBBXWXA+xMLQWZKWawBxYjp6DBlSE3v9/UcvKBvr1vv2tTOhipiogM8rRmxlhrVA==", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Runtime.CompilerServices.Unsafe": "4.5.3" } } }, diff --git a/tests/SharpCompress.Test/packages.lock.json b/tests/SharpCompress.Test/packages.lock.json index 2d35029e..1f290aa4 100644 --- a/tests/SharpCompress.Test/packages.lock.json +++ b/tests/SharpCompress.Test/packages.lock.json @@ -139,6 +139,11 @@ "System.Security.Principal.Windows": "5.0.0" } }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, "System.Collections.Immutable": { "type": "Transitive", "resolved": "6.0.0", @@ -157,10 +162,20 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, "System.Numerics.Vectors": { "type": "Transitive", - "resolved": "4.6.1", - "contentHash": "sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==" + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, "System.Reflection.Metadata": { "type": "Transitive", @@ -172,8 +187,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.1.2", - "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Security.AccessControl": { "type": "Transitive", @@ -190,17 +205,12 @@ }, "System.Threading.Tasks.Extensions": { "type": "Transitive", - "resolved": "4.6.3", - "contentHash": "7sCiwilJLYbTZELaKnc7RecBBXWXA+xMLQWZKWawBxYjp6DBlSE3v9/UcvKBvr1vv2tTOhipiogM8rRmxlhrVA==", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Runtime.CompilerServices.Unsafe": "4.5.3" } }, - "System.ValueTuple": { - "type": "Transitive", - "resolved": "4.6.1", - "contentHash": "+RJT4qaekpZ7DDLhf+LTjq+E48jieKiY9ulJ+BoxKmZblIJfIJT8Ufcaa/clQqnYvWs8jugfGSMu8ylS0caG0w==" - }, "xunit.analyzers": { "type": "Transitive", "resolved": "1.27.0", @@ -275,50 +285,54 @@ "sharpcompress": { "type": "Project", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "[10.0.0, )", - "System.Buffers": "[4.6.1, )", - "System.Memory": "[4.6.3, )", - "System.Text.Encoding.CodePages": "[10.0.0, )" + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.Text.Encoding.CodePages": "[8.0.0, )" } }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "vFuwSLj9QJBbNR0NeNO4YVASUbokxs+i/xbuu8B+Fs4FAZg5QaFa6eGrMaRqTzzNI5tAb97T7BhSxtLckFyiRA==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { - "System.Threading.Tasks.Extensions": "4.6.3" - } - }, - "System.Buffers": { - "type": "CentralTransitive", - "requested": "[4.6.1, )", - "resolved": "4.6.1", - "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" - }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.3, )", - "resolved": "4.6.3", - "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==", - "dependencies": { - "System.Buffers": "4.6.1", - "System.Numerics.Vectors": "4.6.1", - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Threading.Tasks.Extensions": "4.5.4" } }, "System.Text.Encoding.CodePages": { "type": "CentralTransitive", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "QLP54mIATaBpjGlsZIxga38VPk1G9js0Kw651B+bvrXi2kSgGZYrxJSpM3whhTZCBK4HEBHX3fzfDQMw7CXHGQ==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", "dependencies": { - "System.Memory": "4.6.3", - "System.Runtime.CompilerServices.Unsafe": "6.1.2", - "System.ValueTuple": "4.6.1" + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } } }, + ".NETFramework,Version=v4.8/win-x86": { + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + } + }, "net10.0": { "AwesomeAssertions": { "type": "Direct", @@ -527,9 +541,16 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "vFuwSLj9QJBbNR0NeNO4YVASUbokxs+i/xbuu8B+Fs4FAZg5QaFa6eGrMaRqTzzNI5tAb97T7BhSxtLckFyiRA==" + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==" + } + }, + "net10.0/win-x86": { + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==" } } } From 19d11b088295942a1831cf457bacfc81857ed9e7 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sun, 22 Feb 2026 10:43:37 +0000 Subject: [PATCH 7/9] post-merge restore --- src/SharpCompress/packages.lock.json | 48 ++++++++------------- tests/SharpCompress.Test/packages.lock.json | 38 ---------------- 2 files changed, 18 insertions(+), 68 deletions(-) diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index 9ccc7be8..06de73fa 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -206,9 +206,9 @@ ".NETStandard,Version=v2.1": { "Microsoft.Bcl.AsyncInterfaces": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "vFuwSLj9QJBbNR0NeNO4YVASUbokxs+i/xbuu8B+Fs4FAZg5QaFa6eGrMaRqTzzNI5tAb97T7BhSxtLckFyiRA==" + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -235,25 +235,13 @@ "resolved": "17.14.15", "contentHash": "mXQPJsbuUD2ydq4/ffd8h8tSOFCXec+2xJOVNCvXjuMOq/+5EKHq3D2m2MC2+nUaXeFMSt66VS/J4HdKBixgcw==" }, - "System.Buffers": { - "type": "Direct", - "requested": "[4.6.1, )", - "resolved": "4.6.1", - "contentHash": "N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==" - }, - "System.Memory": { - "type": "Direct", - "requested": "[4.6.3, )", - "resolved": "4.6.3", - "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==" - }, "System.Text.Encoding.CodePages": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "QLP54mIATaBpjGlsZIxga38VPk1G9js0Kw651B+bvrXi2kSgGZYrxJSpM3whhTZCBK4HEBHX3fzfDQMw7CXHGQ==", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==", "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.1.2" + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Microsoft.Build.Tasks.Git": { @@ -273,16 +261,16 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "6.1.2", - "contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" } }, "net10.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.3, )", - "resolved": "10.0.3", - "contentHash": "0B6nZyCHWXnvmlB559oduOspVdNOnpNXPjhpWVMovLPAsDVG7A4jJR9rzECf67JUzxP8/ee/wA8clwIzJcWNFA==" + "requested": "[10.0.0, )", + "resolved": "10.0.0", + "contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -454,9 +442,9 @@ "net8.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[8.0.24, )", - "resolved": "8.0.24", - "contentHash": "1gnadp//+DoGJvV4AFdzPqYPxkypaWYjYMCr7KAacV0iadsHz1nU+rrkoxBCna4FCmeKH49CisEwa7g94/MbEg==" + "requested": "[8.0.22, )", + "resolved": "8.0.22", + "contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -502,9 +490,9 @@ "net9.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[9.0.13, )", - "resolved": "9.0.13", - "contentHash": "f7t15I9ZXV7fNk3FIzPAlkJNG1A1tkSeDpRh+TFWEToGGqA+uj6uqU15I8YOkkYICNY2tqOVm2CMe6ScPFPwEg==" + "requested": "[9.0.11, )", + "resolved": "9.0.11", + "contentHash": "vvB9rtDmWaXgYkViT00KORBVmA3pcYsHlgd9vOPqL9sf5bKy3rvLMF1+sI1uUfVj28S3itirHlHmX5/kcpZKNw==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", diff --git a/tests/SharpCompress.Test/packages.lock.json b/tests/SharpCompress.Test/packages.lock.json index 27e27d5d..972b9be4 100644 --- a/tests/SharpCompress.Test/packages.lock.json +++ b/tests/SharpCompress.Test/packages.lock.json @@ -309,30 +309,6 @@ } } }, - ".NETFramework,Version=v4.8/win-x86": { - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", - "dependencies": { - "System.Security.AccessControl": "5.0.0", - "System.Security.Principal.Windows": "5.0.0" - } - }, - "System.Security.AccessControl": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", - "dependencies": { - "System.Security.Principal.Windows": "5.0.0" - } - }, - "System.Security.Principal.Windows": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" - } - }, "net10.0": { "AwesomeAssertions": { "type": "Direct", @@ -545,20 +521,6 @@ "resolved": "8.0.0", "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==" } - }, - "net10.0/win-x86": { - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==" - } - }, - "net10.0/win-x86": { - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==" - } } } } \ No newline at end of file From 0d913f6bbc24abc051f9683a241427f87c344f8a Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sun, 22 Feb 2026 13:19:04 +0000 Subject: [PATCH 8/9] some code fixes --- .../Readers/ReaderFactory.Async.cs | 2 +- .../Readers/Tar/TarReader.Factory.cs | 3 ++- src/SharpCompress/Utility.Async.cs | 8 +++--- src/SharpCompress/Writers/WriterFactory.cs | 26 +++++++++++-------- tests/SharpCompress.Test/WriterTests.cs | 2 +- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/SharpCompress/Readers/ReaderFactory.Async.cs b/src/SharpCompress/Readers/ReaderFactory.Async.cs index 920b0645..e3f3a4be 100644 --- a/src/SharpCompress/Readers/ReaderFactory.Async.cs +++ b/src/SharpCompress/Readers/ReaderFactory.Async.cs @@ -43,7 +43,7 @@ public static partial class ReaderFactory { options ??= ReaderOptions.ForOwnedFile; var stream = fileInfo.OpenAsyncReadStream(cancellationToken); - return await OpenAsyncReader(stream, options, cancellationToken); + return await OpenAsyncReader(stream, options, cancellationToken).ConfigureAwait(false); } public static async ValueTask OpenAsyncReader( diff --git a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs index ac002eca..13c8453c 100644 --- a/src/SharpCompress/Readers/Tar/TarReader.Factory.cs +++ b/src/SharpCompress/Readers/Tar/TarReader.Factory.cs @@ -141,7 +141,8 @@ public partial class TarReader { readerOptions ??= new ReaderOptions() { LeaveStreamOpen = false }; var stream = fileInfo.OpenAsyncReadStream(cancellationToken); - return await OpenAsyncReader(stream, readerOptions, cancellationToken); + return await OpenAsyncReader(stream, readerOptions, cancellationToken) + .ConfigureAwait(false); } public static IReader OpenReader(string filePath, ReaderOptions? readerOptions = null) diff --git a/src/SharpCompress/Utility.Async.cs b/src/SharpCompress/Utility.Async.cs index dc967568..f717eb31 100644 --- a/src/SharpCompress/Utility.Async.cs +++ b/src/SharpCompress/Utility.Async.cs @@ -133,7 +133,7 @@ internal static partial class Utility { cancellationToken.ThrowIfCancellationRequested(); -#if !LEGACY_DOTNET +#if NET8_0_OR_GREATER // Use File.OpenHandle with async options for .NET 8.0+ var handle = File.OpenHandle( path, @@ -144,7 +144,7 @@ internal static partial class Utility ); return new FileStream(handle, FileAccess.Write); #else - // For legacy .NET, use FileStream constructor with async options + // For older target frameworks, use FileStream constructor with async options return new FileStream( path, FileMode.Create, @@ -185,7 +185,7 @@ internal static partial class Utility { cancellationToken.ThrowIfCancellationRequested(); -#if !LEGACY_DOTNET +#if NET8_0_OR_GREATER // Use File.OpenHandle with async options for .NET 8.0+ var handle = File.OpenHandle( path, @@ -196,7 +196,7 @@ internal static partial class Utility ); return new FileStream(handle, FileAccess.Read); #else - // For legacy .NET, use FileStream constructor with async options + // For older target frameworks, use FileStream constructor with async options return new FileStream( path, FileMode.Open, diff --git a/src/SharpCompress/Writers/WriterFactory.cs b/src/SharpCompress/Writers/WriterFactory.cs index 29ff3eed..48ef1d47 100644 --- a/src/SharpCompress/Writers/WriterFactory.cs +++ b/src/SharpCompress/Writers/WriterFactory.cs @@ -43,11 +43,12 @@ public static class WriterFactory { filePath.NotNullOrEmpty(nameof(filePath)); return await OpenAsyncWriter( - new FileInfo(filePath), - archiveType, - writerOptions, - cancellationToken - ); + new FileInfo(filePath), + archiveType, + writerOptions, + cancellationToken + ) + .ConfigureAwait(false); } public static async ValueTask OpenAsyncWriter( @@ -60,11 +61,12 @@ public static class WriterFactory fileInfo.NotNull(nameof(fileInfo)); var stream = fileInfo.OpenAsyncWriteStream(cancellationToken); return await OpenAsyncWriter( - stream, - archiveType, - writerOptions.WithLeaveStreamOpen(false), - cancellationToken - ); + stream, + archiveType, + writerOptions.WithLeaveStreamOpen(false), + cancellationToken + ) + .ConfigureAwait(false); } public static IWriter OpenWriter( @@ -106,7 +108,9 @@ public static class WriterFactory if (factory != null) { - return await factory.OpenAsyncWriter(stream, writerOptions, cancellationToken); + return await factory + .OpenAsyncWriter(stream, writerOptions, cancellationToken) + .ConfigureAwait(false); } throw new NotSupportedException("Archive Type does not have a Writer: " + archiveType); diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs index 2e441735..8ceefa9b 100644 --- a/tests/SharpCompress.Test/WriterTests.cs +++ b/tests/SharpCompress.Test/WriterTests.cs @@ -70,7 +70,7 @@ public class WriterTests : TestBase writerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default; - using var writer = WriterFactory.OpenAsyncWriter( + await using var writer = await WriterFactory.OpenAsyncWriter( stream, _type, writerOptions, From 8d24dff9676aa05184feaa53e49d2e20a0d2a84c Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sun, 22 Feb 2026 13:22:37 +0000 Subject: [PATCH 9/9] fix aot --- src/SharpCompress/SharpCompress.csproj | 2 +- src/SharpCompress/packages.lock.json | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index bf8579ac..7cf1686a 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -31,7 +31,7 @@ $(DefineConstants);LEGACY_DOTNET - + true true diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index 06de73fa..5059aafe 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -488,12 +488,6 @@ } }, "net9.0": { - "Microsoft.NET.ILLink.Tasks": { - "type": "Direct", - "requested": "[9.0.11, )", - "resolved": "9.0.11", - "contentHash": "vvB9rtDmWaXgYkViT00KORBVmA3pcYsHlgd9vOPqL9sf5bKy3rvLMF1+sI1uUfVj28S3itirHlHmX5/kcpZKNw==" - }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", "requested": "[1.0.3, )",