mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
Add new feature to allow injection of an action into the extraction process. 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:
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.IO;
|
||||
using SharpCompress.Readers;
|
||||
@@ -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)
|
||||
{
|
||||
@@ -32,7 +33,7 @@ namespace SharpCompress.Archives
|
||||
{
|
||||
using (Stream s = new ListeningStream(streamListener, entryStream))
|
||||
{
|
||||
s.TransferTo(streamToWriteTo);
|
||||
s.TransferTo(streamToWriteTo, partTransferredAction);
|
||||
}
|
||||
}
|
||||
streamListener.FireEntryExtractionEnd(archiveEntry);
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace SharpCompress.Readers
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteEntryTo(Stream writableStream)
|
||||
public void WriteEntryTo(Stream writableStream, Action<long, int> partTransferredAction = null)
|
||||
{
|
||||
if (wroteCurrentEntry)
|
||||
{
|
||||
@@ -175,22 +175,21 @@ namespace SharpCompress.Readers
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace SharpCompress.Readers
|
||||
/// 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();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#if !NO_FILE
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common;
|
||||
#endif
|
||||
@@ -39,8 +40,12 @@ namespace SharpCompress.Readers
|
||||
/// <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);
|
||||
@@ -66,7 +71,7 @@ namespace SharpCompress.Readers
|
||||
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
reader.WriteEntryToFile(destinationFileName, options);
|
||||
reader.WriteEntryToFile(destinationFileName, options, partTransferredAction);
|
||||
}
|
||||
else if (options.ExtractFullPath && !Directory.Exists(destinationFileName))
|
||||
{
|
||||
@@ -77,8 +82,12 @@ namespace SharpCompress.Readers
|
||||
/// <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()
|
||||
@@ -92,7 +101,7 @@ namespace SharpCompress.Readers
|
||||
}
|
||||
using (FileStream fs = File.Open(destinationFileName, fm))
|
||||
{
|
||||
reader.WriteEntryTo(fs);
|
||||
reader.WriteEntryTo(fs, partTransferredAction);
|
||||
//using (Stream s = reader.OpenEntryStream())
|
||||
//{
|
||||
// s.TransferTo(fs);
|
||||
|
||||
@@ -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> 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;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SharpCompress.Writers
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace SharpCompress.Writers.GZip
|
||||
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)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace SharpCompress.Writers.GZip
|
||||
GZipStream stream = OutputStream as GZipStream;
|
||||
stream.FileName = filename;
|
||||
stream.LastModified = modificationTime;
|
||||
source.TransferTo(stream);
|
||||
source.TransferTo(stream, partTransferredAction);
|
||||
wroteToStream = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,9 @@ namespace SharpCompress.Writers.Tar
|
||||
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)
|
||||
@@ -57,7 +57,7 @@ namespace SharpCompress.Writers.Tar
|
||||
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)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ namespace SharpCompress.Writers.Tar
|
||||
header.Name = NormalizeFilename(filename);
|
||||
header.Size = realSize;
|
||||
header.Write(OutputStream);
|
||||
size = source.TransferTo(OutputStream);
|
||||
size = source.TransferTo(OutputStream, partTransferredAction);
|
||||
PadTo512(size.Value, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,19 +90,19 @@ namespace SharpCompress.Writers.Zip
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user