Add new event to be able to track progress of extraction of individual entry when extracting an archive. This allows for showing or logging progress of the extraction process, especially useful for large files that might take a long time to extract.

This commit is contained in:
Anders Gardebring
2017-04-24 13:50:45 +02:00
parent b8ef1ecafc
commit 683d2714d0
6 changed files with 45 additions and 5 deletions

View File

@@ -4,11 +4,13 @@ namespace SharpCompress.Common
{
public class ReaderExtractionEventArgs<T> : EventArgs
{
internal ReaderExtractionEventArgs(T entry)
internal ReaderExtractionEventArgs(T entry, params object[] paramList)
{
Item = entry;
ParamList = paramList;
}
public T Item { get; private set; }
public object[] ParamList { get; private set; }
}
}

View File

@@ -19,6 +19,7 @@ namespace SharpCompress.Readers
public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionBegin;
public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionEnd;
public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionProgress;
public event EventHandler<CompressedBytesReadEventArgs> CompressedBytesRead;
public event EventHandler<FilePartExtractionBeginEventArgs> FilePartExtractionBegin;
@@ -181,16 +182,16 @@ namespace SharpCompress.Readers
var streamListener = this as IReaderExtractionListener;
streamListener.FireEntryExtractionBegin(Entry);
Write(writableStream);
Write(writableStream, streamListener);
streamListener.FireEntryExtractionEnd(Entry);
wroteCurrentEntry = true;
}
internal void Write(Stream writeStream)
internal void Write(Stream writeStream, IReaderExtractionListener streamListener)
{
using (Stream s = OpenEntryStream())
{
s.TransferTo(writeStream);
s.TransferTo(writeStream, (sizeTransferred, iterations) => streamListener.FireEntryExtractionProgress(Entry, sizeTransferred, iterations));
}
}
@@ -255,6 +256,14 @@ namespace SharpCompress.Readers
}
}
void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations)
{
if (EntryExtractionProgress != null)
{
EntryExtractionProgress(this, new ReaderExtractionEventArgs<IEntry>(entry, new ReaderProgress(entry, bytesTransferred, iterations)));
}
}
void IReaderExtractionListener.FireEntryExtractionEnd(Entry entry)
{
if (EntryExtractionEnd != null)

View File

@@ -8,6 +8,7 @@ namespace SharpCompress.Readers
{
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionBegin;
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionEnd;
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionProgress;
event EventHandler<CompressedBytesReadEventArgs> CompressedBytesRead;
event EventHandler<FilePartExtractionBeginEventArgs> FilePartExtractionBegin;

View File

@@ -7,5 +7,6 @@ namespace SharpCompress.Readers
// void EnsureEntriesLoaded();
void FireEntryExtractionBegin(Entry entry);
void FireEntryExtractionEnd(Entry entry);
void FireEntryExtractionProgress(Entry entry, long sizeTransferred, int iterations);
}
}

View File

@@ -0,0 +1,24 @@
using System;
using SharpCompress.Common;
namespace SharpCompress.Readers
{
public class ReaderProgress
{
private readonly IEntry _entry;
public long BytesTransferred { get; private set; }
public int Iterations { get; private set; }
public int PercentageRead => (int)Math.Round(PercentageReadExact);
public double PercentageReadExact => (float)BytesTransferred / _entry.Size * 100;
public ReaderProgress(IEntry entry, long bytesTransferred, int iterations)
{
_entry = entry;
BytesTransferred = bytesTransferred;
Iterations = iterations;
}
}
}

View File

@@ -229,15 +229,18 @@ namespace SharpCompress
return DosDateToDateTime((UInt32)iTime);
}
public static long TransferTo(this Stream source, Stream destination)
public static long TransferTo(this Stream source, Stream destination, Action<long, int> action = null)
{
byte[] array = new byte[81920];
int count;
var iterations = 0;
long total = 0;
while ((count = source.Read(array, 0, array.Length)) != 0)
{
total += count;
destination.Write(array, 0, count);
iterations++;
action?.Invoke(total, iterations);
}
return total;
}