Refactor to use ProgressReportingStream for progress tracking

Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-05 11:55:29 +00:00
parent 9291f58091
commit 3396f8fe00
2 changed files with 37 additions and 97 deletions

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.IO;
namespace SharpCompress.Archives;
@@ -28,26 +29,8 @@ public static class IArchiveEntryExtensions
}
using var entryStream = archiveEntry.OpenEntryStream();
if (progress is null)
{
entryStream.CopyTo(streamToWriteTo);
}
else
{
var entryPath = archiveEntry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(archiveEntry);
long transferred = 0;
var buffer = new byte[BufferSize];
int bytesRead;
while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0)
{
streamToWriteTo.Write(buffer, 0, bytesRead);
transferred += bytesRead;
progress.Report(new ProgressReport(entryPath, transferred, totalBytes));
}
}
var sourceStream = WrapWithProgress(entryStream, archiveEntry, progress);
sourceStream.CopyTo(streamToWriteTo, BufferSize);
}
/// <summary>
@@ -70,36 +53,26 @@ public static class IArchiveEntryExtensions
}
using var entryStream = archiveEntry.OpenEntryStream();
var sourceStream = WrapWithProgress(entryStream, archiveEntry, progress);
await sourceStream
.CopyToAsync(streamToWriteTo, BufferSize, cancellationToken)
.ConfigureAwait(false);
}
private static Stream WrapWithProgress(
Stream source,
IArchiveEntry entry,
IProgress<ProgressReport>? progress
)
{
if (progress is null)
{
await entryStream
.CopyToAsync(streamToWriteTo, BufferSize, cancellationToken)
.ConfigureAwait(false);
return source;
}
else
{
var entryPath = archiveEntry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(archiveEntry);
long transferred = 0;
var buffer = new byte[BufferSize];
int bytesRead;
while (
(
bytesRead = await entryStream
.ReadAsync(buffer, 0, buffer.Length, cancellationToken)
.ConfigureAwait(false)
) > 0
)
{
await streamToWriteTo
.WriteAsync(buffer, 0, bytesRead, cancellationToken)
.ConfigureAwait(false);
transferred += bytesRead;
progress.Report(new ProgressReport(entryPath, transferred, totalBytes));
}
}
var entryPath = entry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(entry);
return new ProgressReportingStream(source, progress, entryPath, totalBytes, leaveOpen: true);
}
private static long? GetEntrySizeSafe(IArchiveEntry entry)

View File

@@ -261,22 +261,36 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader
internal void Write(Stream writeStream)
{
using Stream s = OpenEntryStream();
TransferWithProgress(s, writeStream, Entry);
var sourceStream = WrapWithProgress(s, Entry);
sourceStream.CopyTo(writeStream, 81920);
}
internal async Task WriteAsync(Stream writeStream, CancellationToken cancellationToken)
{
#if NETFRAMEWORK || NETSTANDARD2_0
using Stream s = OpenEntryStream();
await TransferWithProgressAsync(s, writeStream, Entry, cancellationToken)
.ConfigureAwait(false);
var sourceStream = WrapWithProgress(s, Entry);
await sourceStream.CopyToAsync(writeStream, 81920, cancellationToken).ConfigureAwait(false);
#else
await using Stream s = OpenEntryStream();
await TransferWithProgressAsync(s, writeStream, Entry, cancellationToken)
.ConfigureAwait(false);
var sourceStream = WrapWithProgress(s, Entry);
await sourceStream.CopyToAsync(writeStream, 81920, cancellationToken).ConfigureAwait(false);
#endif
}
private Stream WrapWithProgress(Stream source, Entry entry)
{
var progress = Options.Progress;
if (progress is null)
{
return source;
}
var entryPath = entry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(entry);
return new ProgressReportingStream(source, progress, entryPath, totalBytes, leaveOpen: true);
}
private static long? GetEntrySizeSafe(Entry entry)
{
try
@@ -292,53 +306,6 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader
}
}
private void TransferWithProgress(Stream source, Stream destination, Entry entry)
{
var progress = Options.Progress;
var entryPath = entry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(entry);
long transferred = 0;
var buffer = new byte[81920];
int bytesRead;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
destination.Write(buffer, 0, bytesRead);
transferred += bytesRead;
progress?.Report(new ProgressReport(entryPath, transferred, totalBytes));
}
}
private async Task TransferWithProgressAsync(
Stream source,
Stream destination,
Entry entry,
CancellationToken cancellationToken
)
{
var progress = Options.Progress;
var entryPath = entry.Key ?? string.Empty;
long? totalBytes = GetEntrySizeSafe(entry);
long transferred = 0;
var buffer = new byte[81920];
int bytesRead;
while (
(
bytesRead = await source
.ReadAsync(buffer, 0, buffer.Length, cancellationToken)
.ConfigureAwait(false)
) > 0
)
{
await destination
.WriteAsync(buffer, 0, bytesRead, cancellationToken)
.ConfigureAwait(false);
transferred += bytesRead;
progress?.Report(new ProgressReport(entryPath, transferred, totalBytes));
}
}
public EntryStream OpenEntryStream()
{
if (_wroteCurrentEntry)