more methods for async

This commit is contained in:
Adam Hathcock
2025-10-17 11:01:37 +01:00
parent e30a88e634
commit d1409d6dde
8 changed files with 67 additions and 39 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Factories;
using SharpCompress.IO;
@@ -116,14 +117,14 @@ public static class ArchiveFactory
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteToDirectory(
public static async Task WriteToDirectoryAsync(
string sourceArchive,
string destinationDirectory,
ExtractionOptions? options = null
)
{
using var archive = Open(sourceArchive);
archive.WriteToDirectory(destinationDirectory, options);
await archive.WriteToDirectoryAsync(destinationDirectory, options);
}
private static T FindFactory<T>(FileInfo finfo)

View File

@@ -1,4 +1,5 @@
using System.IO;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.IO;
@@ -6,7 +7,7 @@ namespace SharpCompress.Archives;
public static class IArchiveEntryExtensions
{
public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo)
public static async Task WriteToAsync(this IArchiveEntry archiveEntry, Stream streamToWriteTo)
{
if (archiveEntry.IsDirectory)
{
@@ -21,11 +22,11 @@ public static class IArchiveEntryExtensions
archiveEntry.Size,
archiveEntry.CompressedSize
);
var entryStream = archiveEntry.OpenEntryStream();
var entryStream = await archiveEntry.OpenEntryStreamAsync();
using (entryStream)
{
using Stream s = new ListeningStream(streamListener, entryStream);
s.TransferTo(streamToWriteTo);
await s.TransferToAsync(streamToWriteTo);
}
streamListener.FireEntryExtractionEnd(archiveEntry);
}
@@ -33,34 +34,34 @@ public static class IArchiveEntryExtensions
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteToDirectory(
public static async Task WriteEntryToDirectoryAsync(
this IArchiveEntry entry,
string destinationDirectory,
ExtractionOptions? options = null
) =>
ExtractionMethods.WriteEntryToDirectory(
await ExtractionMethods.WriteEntryToDirectoryAsync(
entry,
destinationDirectory,
options,
entry.WriteToFile
entry.WriteToFileAsync
);
/// <summary>
/// Extract to specific file
/// </summary>
public static void WriteToFile(
public static Task WriteToFileAsync(
this IArchiveEntry entry,
string destinationFileName,
ExtractionOptions? options = null
) =>
ExtractionMethods.WriteEntryToFile(
ExtractionMethods.WriteEntryToFileAsync(
entry,
destinationFileName,
options,
(x, fm) =>
async (x, fm) =>
{
using var fs = File.Open(destinationFileName, fm);
entry.WriteTo(fs);
await entry.WriteToAsync(fs);
}
);
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Readers;
@@ -13,14 +14,14 @@ public static class IArchiveExtensions
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteToDirectory(
public static async Task WriteToDirectoryAsync(
this IArchive archive,
string destinationDirectory,
ExtractionOptions? options = null
)
{
using var reader = archive.ExtractAllEntries();
reader.WriteAllToDirectory(destinationDirectory, options);
await reader.WriteAllToDirectoryAsync(destinationDirectory, options);
}
/// <summary>
@@ -30,7 +31,7 @@ public static class IArchiveExtensions
/// <param name="destination">The folder to extract into.</param>
/// <param name="progressReport">Optional progress report callback.</param>
/// <param name="cancellationToken">Optional cancellation token.</param>
public static void ExtractToDirectory(
public static async Task ExtractToDirectory(
this IArchive archive,
string destination,
Action<double>? progressReport = null,
@@ -46,7 +47,7 @@ public static class IArchiveExtensions
// Extract
var entries = archive.ExtractAllEntries();
while (entries.MoveToNextEntry())
while (await entries.MoveToNextEntryAsync())
{
cancellationToken.ThrowIfCancellationRequested();
@@ -77,7 +78,7 @@ public static class IArchiveExtensions
// Write file
using var fs = File.OpenWrite(path);
entries.WriteEntryTo(fs);
await entries.WriteEntryToAsync(fs);
// Update progress
bytesRead += entry.Size;

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Common.SevenZip;
using SharpCompress.Compressors.LZMA.Utilites;
@@ -253,8 +254,8 @@ public class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, SevenZipVol
}
}
protected override EntryStream GetEntryStream() =>
CreateEntryStream(
protected override Task<EntryStream> GetEntryStreamAsync() =>
CreateEntryStreamAsync(
new ReadOnlySubStream(
_currentStream.NotNull("currentStream is not null"),
_currentItem?.Size ?? 0

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Threading.Tasks;
namespace SharpCompress.Common;
@@ -8,11 +9,11 @@ internal static class ExtractionMethods
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteEntryToDirectory(
public static async Task WriteEntryToDirectoryAsync(
IEntry entry,
string destinationDirectory,
ExtractionOptions? options,
Action<string, ExtractionOptions?> write
Func<string, ExtractionOptions?, Task> write
)
{
string destinationFileName;
@@ -77,7 +78,7 @@ internal static class ExtractionMethods
"Entry is trying to write a file outside of the destination directory."
);
}
write(destinationFileName, options);
await write(destinationFileName, options);
}
else if (options.ExtractFullPath && !Directory.Exists(destinationFileName))
{
@@ -85,11 +86,11 @@ internal static class ExtractionMethods
}
}
public static void WriteEntryToFile(
public static async Task WriteEntryToFileAsync(
IEntry entry,
string destinationFileName,
ExtractionOptions? options,
Action<string, FileMode> openAndWrite
Func<string, FileMode, Task> openAndWrite
)
{
if (entry.LinkTarget != null)
@@ -112,7 +113,7 @@ internal static class ExtractionMethods
fm = FileMode.CreateNew;
}
openAndWrite(destinationFileName, fm);
await openAndWrite(destinationFileName, fm);
entry.PreserveExtractionOptions(destinationFileName, options);
}
}

View File

@@ -1,4 +1,5 @@
#if !NETSTANDARD2_0 && !NETFRAMEWORK
#nullable disable
using System;
using SharpCompress.Common;

View File

@@ -1,68 +1,69 @@
using System.IO;
using System.Threading.Tasks;
using SharpCompress.Common;
namespace SharpCompress.Readers;
public static class IReaderExtensions
{
public static void WriteEntryTo(this IReader reader, string filePath)
public static async Task WriteEntryToAsync(this IReader reader, string filePath)
{
using Stream stream = File.Open(filePath, FileMode.Create, FileAccess.Write);
reader.WriteEntryTo(stream);
await reader.WriteEntryToAsync(stream);
}
public static void WriteEntryTo(this IReader reader, FileInfo filePath)
public static async Task WriteEntryToAsync(this IReader reader, FileInfo filePath)
{
using Stream stream = filePath.Open(FileMode.Create);
reader.WriteEntryTo(stream);
await reader.WriteEntryToAsync(stream);
}
/// <summary>
/// Extract all remaining unread entries to specific directory, retaining filename
/// </summary>
public static void WriteAllToDirectory(
public static async Task WriteAllToDirectoryAsync(
this IReader reader,
string destinationDirectory,
ExtractionOptions? options = null
)
{
while (reader.MoveToNextEntry())
while (await reader.MoveToNextEntryAsync())
{
reader.WriteEntryToDirectory(destinationDirectory, options);
await reader.WriteEntryToDirectoryAsync(destinationDirectory, options);
}
}
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteEntryToDirectory(
public static async Task WriteEntryToDirectoryAsync(
this IReader reader,
string destinationDirectory,
ExtractionOptions? options = null
) =>
ExtractionMethods.WriteEntryToDirectory(
await ExtractionMethods.WriteEntryToDirectoryAsync(
reader.Entry,
destinationDirectory,
options,
reader.WriteEntryToFile
reader.WriteEntryToFileAsync
);
/// <summary>
/// Extract to specific file
/// </summary>
public static void WriteEntryToFile(
public static async Task WriteEntryToFileAsync(
this IReader reader,
string destinationFileName,
ExtractionOptions? options = null
) =>
ExtractionMethods.WriteEntryToFile(
await ExtractionMethods.WriteEntryToFileAsync(
reader.Entry,
destinationFileName,
options,
(x, fm) =>
async (x, fm) =>
{
using var fs = File.Open(destinationFileName, fm);
reader.WriteEntryTo(fs);
await reader.WriteEntryToAsync(fs);
}
);
}

View File

@@ -304,6 +304,26 @@ internal static class Utility
}
}
public static async Task<long> TransferToAsync(this Stream source, Stream destination)
{
var array = GetTransferByteArray();
try
{
long total = 0;
int count;
while ((count = await source.ReadAsync(array, 0, array.Length)) != 0)
{
await destination.WriteAsync(array, 0, count);
total += count;
}
return total;
}
finally
{
ArrayPool<byte>.Shared.Return(array);
}
}
public static long TransferTo(this Stream source, Stream destination, long maxLength)
{
var array = GetTransferByteArray();
@@ -365,6 +385,7 @@ internal static class Utility
}
}
private static bool ReadTransferBlock(Stream source, byte[] array, out int count) =>
(count = source.Read(array, 0, array.Length)) != 0;