Skip to content

Commit

Permalink
Add new feature to allow injection of an action into the extraction p…
Browse files Browse the repository at this point in the history
…rocess. This allows for showing or logging progress of the extraction process, especially useful for large files that might take a long time to extract.
  • Loading branch information
Anders Gardebring committed Apr 20, 2017
1 parent 58b4fe4 commit 467fc2d
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 29 deletions.
7 changes: 4 additions & 3 deletions src/SharpCompress/Archives/IArchiveEntryExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.IO;
using SharpCompress.Readers;
Expand All @@ -7,7 +8,7 @@ namespace SharpCompress.Archives
{
public static class IArchiveEntryExtensions
{
public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo)
public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo, Action<long, int> partTransferredAction = null)
{
if (archiveEntry.Archive.Type == ArchiveType.Rar && archiveEntry.Archive.IsSolid)
{
Expand All @@ -32,7 +33,7 @@ public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWrite
{
using (Stream s = new ListeningStream(streamListener, entryStream))
{
s.TransferTo(streamToWriteTo);
s.TransferTo(streamToWriteTo, partTransferredAction);
}
}
streamListener.FireEntryExtractionEnd(archiveEntry);
Expand Down
11 changes: 5 additions & 6 deletions src/SharpCompress/Readers/AbstractReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,30 +167,29 @@ private void Skip()
}
}

public void WriteEntryTo(Stream writableStream)
public void WriteEntryTo(Stream writableStream, Action<long, int> partTransferredAction = null)
{
if (wroteCurrentEntry)
{
throw new ArgumentException("WriteEntryTo or OpenEntryStream can only be called once.");
}
if ((writableStream == null) || (!writableStream.CanWrite))
{
throw new ArgumentNullException(
"A writable Stream was required. Use Cancel if that was intended.");
throw new ArgumentNullException("A writable Stream was required. Use Cancel if that was intended.");
}

var streamListener = this as IReaderExtractionListener;
streamListener.FireEntryExtractionBegin(Entry);
Write(writableStream);
Write(writableStream, partTransferredAction);
streamListener.FireEntryExtractionEnd(Entry);
wroteCurrentEntry = true;
}

internal void Write(Stream writeStream)
internal void Write(Stream writeStream, Action<long, int> partTransferredAction = null)
{
using (Stream s = OpenEntryStream())
{
s.TransferTo(writeStream);
s.TransferTo(writeStream, partTransferredAction);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/SharpCompress/Readers/IReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public interface IReader : IDisposable
/// Decompresses the current entry to the stream. This cannot be called twice for the current entry.
/// </summary>
/// <param name="writableStream"></param>
void WriteEntryTo(Stream writableStream);
/// <param name="partTransferredAction"></param>
void WriteEntryTo(Stream writableStream, Action<long, int> partTransferredAction = null);

bool Cancelled { get; }
void Cancel();
Expand Down
21 changes: 15 additions & 6 deletions src/SharpCompress/Readers/IReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if !NO_FILE
using System;
using System.IO;
using SharpCompress.Common;
#endif
Expand Down Expand Up @@ -39,8 +40,12 @@ public static void WriteEntryTo(this IReader reader, FileInfo filePath)
/// <summary>
/// Extract to specific directory, retaining filename
/// </summary>
public static void WriteEntryToDirectory(this IReader reader, string destinationDirectory,
ExtractionOptions options = null)
public static void WriteEntryToDirectory(
this IReader reader,
string destinationDirectory,
ExtractionOptions options = null,
Action<long, int> partTransferredAction = null
)
{
string destinationFileName = string.Empty;
string file = Path.GetFileName(reader.Entry.Key);
Expand All @@ -66,7 +71,7 @@ public static void WriteEntryTo(this IReader reader, FileInfo filePath)

if (!reader.Entry.IsDirectory)
{
reader.WriteEntryToFile(destinationFileName, options);
reader.WriteEntryToFile(destinationFileName, options, partTransferredAction);
}
else if (options.ExtractFullPath && !Directory.Exists(destinationFileName))
{
Expand All @@ -77,8 +82,12 @@ public static void WriteEntryTo(this IReader reader, FileInfo filePath)
/// <summary>
/// Extract to specific file
/// </summary>
public static void WriteEntryToFile(this IReader reader, string destinationFileName,
ExtractionOptions options = null)
public static void WriteEntryToFile(
this IReader reader,
string destinationFileName,
ExtractionOptions options = null,
Action<long, int> partTransferredAction = null
)
{
FileMode fm = FileMode.Create;
options = options ?? new ExtractionOptions()
Expand All @@ -92,7 +101,7 @@ public static void WriteEntryTo(this IReader reader, FileInfo filePath)
}
using (FileStream fs = File.Open(destinationFileName, fm))
{
reader.WriteEntryTo(fs);
reader.WriteEntryTo(fs, partTransferredAction);
//using (Stream s = reader.OpenEntryStream())
//{
// s.TransferTo(fs);
Expand Down
5 changes: 4 additions & 1 deletion src/SharpCompress/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,18 @@ public static DateTime DosDateToDateTime(Int32 iTime)
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> partTransferredAction = 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++;
partTransferredAction?.Invoke(total, iterations);
}
return total;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Writers/AbstractWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected void InitalizeStream(Stream stream, bool closeStream)

public ArchiveType WriterType { get; }

public abstract void Write(string filename, Stream source, DateTime? modificationTime);
public abstract void Write(string filename, Stream source, DateTime? modificationTime, Action<long, int> partTransferredAction = null);

protected virtual void Dispose(bool isDisposing)
{
Expand Down
4 changes: 2 additions & 2 deletions src/SharpCompress/Writers/GZip/GZipWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected override void Dispose(bool isDisposing)
base.Dispose(isDisposing);
}

public override void Write(string filename, Stream source, DateTime? modificationTime)
public override void Write(string filename, Stream source, DateTime? modificationTime, Action<long, int> partTransferredAction = null)
{
if (wroteToStream)
{
Expand All @@ -35,7 +35,7 @@ public override void Write(string filename, Stream source, DateTime? modificatio
GZipStream stream = OutputStream as GZipStream;
stream.FileName = filename;
stream.LastModified = modificationTime;
source.TransferTo(stream);
source.TransferTo(stream, partTransferredAction);
wroteToStream = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Writers/IWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace SharpCompress.Writers
public interface IWriter : IDisposable
{
ArchiveType WriterType { get; }
void Write(string filename, Stream source, DateTime? modificationTime);
void Write(string filename, Stream source, DateTime? modificationTime, Action<long, int> partTransferredAction = null);
}
}
8 changes: 4 additions & 4 deletions src/SharpCompress/Writers/Tar/TarWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public TarWriter(Stream destination, WriterOptions options)
InitalizeStream(destination, !options.LeaveStreamOpen);
}

public override void Write(string filename, Stream source, DateTime? modificationTime)
public override void Write(string filename, Stream source, DateTime? modificationTime, Action<long, int> partTransferredAction = null)
{
Write(filename, source, modificationTime, null);
Write(filename, source, modificationTime, null, partTransferredAction);
}

private string NormalizeFilename(string filename)
Expand All @@ -57,7 +57,7 @@ private string NormalizeFilename(string filename)
return filename.Trim('/');
}

public void Write(string filename, Stream source, DateTime? modificationTime, long? size)
public void Write(string filename, Stream source, DateTime? modificationTime, long? size, Action<long, int> partTransferredAction = null)
{
if (!source.CanSeek && size == null)
{
Expand All @@ -71,7 +71,7 @@ public void Write(string filename, Stream source, DateTime? modificationTime, lo
header.Name = NormalizeFilename(filename);
header.Size = realSize;
header.Write(OutputStream);
size = source.TransferTo(OutputStream);
size = source.TransferTo(OutputStream, partTransferredAction);
PadTo512(size.Value, false);
}

Expand Down
8 changes: 4 additions & 4 deletions src/SharpCompress/Writers/Zip/ZipWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,19 @@ private static ZipCompressionMethod ToZipCompressionMethod(CompressionType compr
}
}

public override void Write(string entryPath, Stream source, DateTime? modificationTime)
public override void Write(string entryPath, Stream source, DateTime? modificationTime, Action<long, int> partTransferredAction = null)
{
Write(entryPath, source, new ZipWriterEntryOptions()
{
ModificationDateTime = modificationTime
});
}, partTransferredAction);
}

public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions)
public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions, Action<long, int> partTransferredAction = null)
{
using (Stream output = WriteToStream(entryPath, zipWriterEntryOptions))
{
source.TransferTo(output);
source.TransferTo(output, partTransferredAction);
}
}

Expand Down

0 comments on commit 467fc2d

Please sign in to comment.