Delegates/event handlers for feedback when creating zip files. #14

Open
opened 2026-01-29 22:03:30 +00:00 by claunia · 5 comments
Owner

Originally created by @patoncrispy on GitHub (May 8, 2014).

I'm zipping lots of large files (10GB+) and need to be able to get some information back on how it's doing. Is it possible to get some delegates in place to be able to find out how quickly my file is zipping (bytes read, bytes zipped, current size, files added etc)? It would be really useful for providing feedback to clients waiting for their documents!

Originally created by @patoncrispy on GitHub (May 8, 2014). I'm zipping lots of large files (10GB+) and need to be able to get some information back on how it's doing. Is it possible to get some delegates in place to be able to find out how quickly my file is zipping (bytes read, bytes zipped, current size, files added etc)? It would be really useful for providing feedback to clients waiting for their documents!
Author
Owner

@adamhathcock commented on GitHub (Nov 4, 2014):

There are events on Archive and Reader I believe.

@adamhathcock commented on GitHub (Nov 4, 2014): There are events on Archive and Reader I believe.
Author
Owner

@sepehr1014 commented on GitHub (May 31, 2015):

@adamhathcock Hi, I may be wrong but I don't think there are any events to monitor the progress of creating archives. What am I missing?

@sepehr1014 commented on GitHub (May 31, 2015): @adamhathcock Hi, I may be wrong but I don't think there are any events to monitor the progress of creating archives. What am I missing?
Author
Owner

@adamhathcock commented on GitHub (May 31, 2015):

You're right. There's nothing for creating. Just extraction.

@adamhathcock commented on GitHub (May 31, 2015): You're right. There's nothing for creating. Just extraction.
Author
Owner

@sepehr1014 commented on GitHub (May 31, 2015):

Any plans to add it? We're working on a project which requires compressing/decompressing files. Since in most cases, there are gigabytes of files to be compressed, progress report is essential.

@sepehr1014 commented on GitHub (May 31, 2015): Any plans to add it? We're working on a project which requires compressing/decompressing files. Since in most cases, there are gigabytes of files to be compressed, progress report is essential.
Author
Owner

@Strachu commented on GitHub (May 31, 2015):

Hi,
It is possible to add progress reporting while creating an archive without modification of the library. I am not sure how do you create the archive but I have successfully managed to add the reporting while creating the archive by decorating a source file stream with progress reporting capability.

Some excerpts from my application which may help you in implementing this functionality:
Archive creation:

using(var destinationStream = File.Open(destinationPath, FileMode.Create, FileAccess.Write))
using(var writer = new ZipWriter(destinationStream, new CompressioInfo(), String.Empty))
{
    foreach(var fileEntry in mFiles.Values.Where(file => !file.IsDirectory))
    {
        cancelToken.ThrowIfCancellationRequested();

        var progressReportingDataStream = new ProgressReportingStream(fileEntry.OpenStream(), progress.GetProgressForNextFile());
        var dataStream = new StreamWithCancellationSupport(progressReportingDataStream, cancelToken);

        writer.Write(fileEntry.Path, dataStream, fileEntry.LastModificationTime);
    }
}

ProgressReportingStream:


    /// <summary>
    /// A decorator which adds progress reporting support for reading and writing to streams.
    /// </summary>
    public class ProgressReportingStream : StreamDecorator
    {
        private long                     mTotalBytesProcessed = 0;
        private readonly IProgress<long> mProgress;

        /// <summary>
        /// Initializes a new instance of the <see cref="ProgressReportingStream"/> class.
        /// </summary>
        /// <param name="originalStream">
        /// The original stream to add progress reporting to.
        /// </param>
        /// <param name="progress">
        /// The object which will be notified about the progress. Progress value = total bytes
        /// processed at the moment of report (read + written).
        /// </param>
        public ProgressReportingStream(Stream originalStream, IProgress<long> progress) : base(originalStream)
        {
            Contract.Requires(originalStream != null);

            mProgress = progress ?? new Progress<long>();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesRead = base.Read(buffer, offset, count);

            mTotalBytesProcessed += bytesRead;

            mProgress.Report(mTotalBytesProcessed);

            return bytesRead;
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            var previousPosition = base.Position;
            var newPosition      = base.Seek(offset, origin);

            mTotalBytesProcessed += newPosition - previousPosition;

            mProgress.Report(mTotalBytesProcessed);

            return newPosition;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            base.Write(buffer, offset, count);

            mTotalBytesProcessed += count;

            mProgress.Report(mTotalBytesProcessed);
        }
    }
@Strachu commented on GitHub (May 31, 2015): Hi, It is possible to add progress reporting while creating an archive without modification of the library. I am not sure how do you create the archive but I have successfully managed to add the reporting while creating the archive by decorating a source file stream with progress reporting capability. Some excerpts from my application which may help you in implementing this functionality: Archive creation: ``` C# using(var destinationStream = File.Open(destinationPath, FileMode.Create, FileAccess.Write)) using(var writer = new ZipWriter(destinationStream, new CompressioInfo(), String.Empty)) { foreach(var fileEntry in mFiles.Values.Where(file => !file.IsDirectory)) { cancelToken.ThrowIfCancellationRequested(); var progressReportingDataStream = new ProgressReportingStream(fileEntry.OpenStream(), progress.GetProgressForNextFile()); var dataStream = new StreamWithCancellationSupport(progressReportingDataStream, cancelToken); writer.Write(fileEntry.Path, dataStream, fileEntry.LastModificationTime); } } ``` ProgressReportingStream: ``` C# /// <summary> /// A decorator which adds progress reporting support for reading and writing to streams. /// </summary> public class ProgressReportingStream : StreamDecorator { private long mTotalBytesProcessed = 0; private readonly IProgress<long> mProgress; /// <summary> /// Initializes a new instance of the <see cref="ProgressReportingStream"/> class. /// </summary> /// <param name="originalStream"> /// The original stream to add progress reporting to. /// </param> /// <param name="progress"> /// The object which will be notified about the progress. Progress value = total bytes /// processed at the moment of report (read + written). /// </param> public ProgressReportingStream(Stream originalStream, IProgress<long> progress) : base(originalStream) { Contract.Requires(originalStream != null); mProgress = progress ?? new Progress<long>(); } public override int Read(byte[] buffer, int offset, int count) { int bytesRead = base.Read(buffer, offset, count); mTotalBytesProcessed += bytesRead; mProgress.Report(mTotalBytesProcessed); return bytesRead; } public override long Seek(long offset, SeekOrigin origin) { var previousPosition = base.Position; var newPosition = base.Seek(offset, origin); mTotalBytesProcessed += newPosition - previousPosition; mProgress.Report(mTotalBytesProcessed); return newPosition; } public override void Write(byte[] buffer, int offset, int count) { base.Write(buffer, offset, count); mTotalBytesProcessed += count; mProgress.Report(mTotalBytesProcessed); } } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#14