mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-25 00:15:15 +00:00
Refactor to use ProgressReportingStream for progress tracking
Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user