SaveProgress Event

DotNetZip

Ionic Zip Library v1.9.1.6 SaveProgress Event
ReferenceIonic.ZipZipFileSaveProgress
An event handler invoked when a Save() starts, before and after each entry has been written to the archive, when a Save() completes, and during other Save events.
Declaration Syntax
C# Visual Basic Visual C++
public event EventHandler<SaveProgressEventArgs> SaveProgress
Public Event SaveProgress As EventHandler(Of SaveProgressEventArgs)
public:
 event EventHandler<SaveProgressEventArgs^>^ SaveProgress {
	void add (EventHandler<SaveProgressEventArgs^>^ value);
	void remove (EventHandler<SaveProgressEventArgs^>^ value);
}
Remarks

Depending on the particular event, different properties on the SaveProgressEventArgs parameter are set. The following table summarizes the available EventTypes and the conditions under which this event handler is invoked with a SaveProgressEventArgs with the given EventType.

value of EntryType Meaning and conditions
ZipProgressEventType.Saving_Started
Fired when ZipFile.Save() begins.
ZipProgressEventType.Saving_BeforeSaveEntry
Fired within ZipFile.Save(), just before writing data for each particular entry.
ZipProgressEventType.Saving_AfterSaveEntry
Fired within ZipFile.Save(), just after having finished writing data for each particular entry.
ZipProgressEventType.Saving_Completed
Fired when ZipFile.Save() has completed.
ZipProgressEventType.Saving_AfterSaveTempArchive
Fired after the temporary file has been created. This happens only when saving to a disk file. This event will not be invoked when saving to a stream.
ZipProgressEventType.Saving_BeforeRenameTempArchive
Fired just before renaming the temporary file to the permanent location. This happens only when saving to a disk file. This event will not be invoked when saving to a stream.
ZipProgressEventType.Saving_AfterRenameTempArchive
Fired just after renaming the temporary file to the permanent location. This happens only when saving to a disk file. This event will not be invoked when saving to a stream.
ZipProgressEventType.Saving_AfterCompileSelfExtractor
Fired after a self-extracting archive has finished compiling. This EventType is used only within SaveSelfExtractor().
ZipProgressEventType.Saving_BytesRead
Set during the save of a particular entry, to update progress of the Save(). When this EventType is set, the BytesTransferred is the number of bytes that have been read from the source stream. The TotalBytesToTransfer is the number of bytes in the uncompressed file.
Examples
This example uses an anonymous method to handle the SaveProgress event, by updating a progress bar.
CopyC#
progressBar1.Value = 0;
progressBar1.Max = listbox1.Items.Count;
using (ZipFile zip = new ZipFile())
{
   // listbox1 contains a list of filenames
   zip.AddFiles(listbox1.Items);

   // do the progress bar:
   zip.SaveProgress += (sender, e) => {
      if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) {
         progressBar1.PerformStep();
      }
   };

   zip.Save(fs);
}
Examples
This example uses a named method as the SaveProgress event handler, to update the user, in a console-based application.
CopyC#
static bool justHadByteUpdate= false;
public static void SaveProgress(object sender, SaveProgressEventArgs e)
{
    if (e.EventType == ZipProgressEventType.Saving_Started)
        Console.WriteLine("Saving: {0}", e.ArchiveName);

    else if (e.EventType == ZipProgressEventType.Saving_Completed)
    {
        justHadByteUpdate= false;
        Console.WriteLine();
        Console.WriteLine("Done: {0}", e.ArchiveName);
    }

    else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
    {
        if (justHadByteUpdate)
            Console.WriteLine();
        Console.WriteLine("  Writing: {0} ({1}/{2})",
                          e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal);
        justHadByteUpdate= false;
    }

    else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
    {
        if (justHadByteUpdate)
            Console.SetCursorPosition(0, Console.CursorTop);
         Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
                      e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
        justHadByteUpdate= true;
    }
}

public static ZipUp(string targetZip, string directory)
{
  using (var zip = new ZipFile()) {
    zip.SaveProgress += SaveProgress;
    zip.AddDirectory(directory);
    zip.Save(targetZip);
  }
}
CopyVB.NET
Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String)
    Using zip As ZipFile = New ZipFile
        AddHandler zip.SaveProgress, AddressOf MySaveProgress
        zip.AddDirectory(directory)
        zip.Save(targetZip)
    End Using
End Sub

Private Shared justHadByteUpdate As Boolean = False

Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
    If (e.EventType Is ZipProgressEventType.Saving_Started) Then
        Console.WriteLine("Saving: {0}", e.ArchiveName)

    ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then
        justHadByteUpdate = False
        Console.WriteLine
        Console.WriteLine("Done: {0}", e.ArchiveName)

    ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then
        If justHadByteUpdate Then
            Console.WriteLine
        End If
        Console.WriteLine("  Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal)
        justHadByteUpdate = False

    ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then
        If justHadByteUpdate Then
            Console.SetCursorPosition(0, Console.CursorTop)
        End If
        Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, _
                      e.TotalBytesToTransfer, _
                      (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
        justHadByteUpdate = True
    End If
End Sub
Examples
This is a more complete example of using the SaveProgress events in a Windows Forms application, with a Thread object.
CopyC#
delegate void SaveEntryProgress(SaveProgressEventArgs e);
delegate void ButtonClick(object sender, EventArgs e);

public class WorkerOptions
{
    public string ZipName;
    public string Folder;
    public string Encoding;
    public string Comment;
    public int ZipFlavor;
    public Zip64Option Zip64;
}

private int _progress2MaxFactor;
private bool _saveCanceled;
private long _totalBytesBeforeCompress;
private long _totalBytesAfterCompress;
private Thread _workerThread;


private void btnZipup_Click(object sender, EventArgs e)
{
    KickoffZipup();
}

private void btnCancel_Click(object sender, EventArgs e)
{
    if (this.lblStatus.InvokeRequired)
    {
        this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e });
    }
    else
    {
        _saveCanceled = true;
        lblStatus.Text = "Canceled...";
        ResetState();
    }
}

private void KickoffZipup()
{
    _folderName = tbDirName.Text;

    if (_folderName == null || _folderName == "") return;
    if (this.tbZipName.Text == null || this.tbZipName.Text == "") return;

    // check for existence of the zip file:
    if (System.IO.File.Exists(this.tbZipName.Text))
    {
        var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." +
                                                      "  Do you want to overwrite this file?", this.tbZipName.Text),
                                        "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
        if (dlgResult != DialogResult.Yes) return;
        System.IO.File.Delete(this.tbZipName.Text);
    }

     _saveCanceled = false;
    _nFilesCompleted = 0;
    _totalBytesAfterCompress = 0;
    _totalBytesBeforeCompress = 0;
    this.btnOk.Enabled = false;
    this.btnOk.Text = "Zipping...";
    this.btnCancel.Enabled = true;
    lblStatus.Text = "Zipping...";

    var options = new WorkerOptions
    {
        ZipName = this.tbZipName.Text,
        Folder = _folderName,
        Encoding = "ibm437"
    };

    if (this.comboBox1.SelectedIndex != 0)
    {
        options.Encoding = this.comboBox1.SelectedItem.ToString();
    }

    if (this.radioFlavorSfxCmd.Checked)
        options.ZipFlavor = 2;
    else if (this.radioFlavorSfxGui.Checked)
        options.ZipFlavor = 1;
    else options.ZipFlavor = 0;

    if (this.radioZip64AsNecessary.Checked)
        options.Zip64 = Zip64Option.AsNecessary;
    else if (this.radioZip64Always.Checked)
        options.Zip64 = Zip64Option.Always;
    else options.Zip64 = Zip64Option.Never;

    options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n",
                options.Encoding,
                FlavorToString(options.ZipFlavor),
                options.Zip64.ToString(),
                System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"),
                this.Text);

    if (this.tbComment.Text != TB_COMMENT_NOTE)
        options.Comment += this.tbComment.Text;

    _workerThread = new Thread(this.DoSave);
    _workerThread.Name = "Zip Saver thread";
    _workerThread.Start(options);
    this.Cursor = Cursors.WaitCursor;
 }


private void DoSave(Object p)
{
    WorkerOptions options = p as WorkerOptions;
    try
    {
        using (var zip1 = new ZipFile())
        {
            zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding);
            zip1.Comment = options.Comment;
            zip1.AddDirectory(options.Folder);
            _entriesToZip = zip1.EntryFileNames.Count;
            SetProgressBars();
            zip1.SaveProgress += this.zip1_SaveProgress;

            zip1.UseZip64WhenSaving = options.Zip64;

            if (options.ZipFlavor == 1)
                zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication);
            else if (options.ZipFlavor == 2)
                zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication);
            else
                zip1.Save(options.ZipName);
        }
    }
    catch (System.Exception exc1)
    {
        MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message));
        btnCancel_Click(null, null);
    }
}



void zip1_SaveProgress(object sender, SaveProgressEventArgs e)
{
    switch (e.EventType)
    {
        case ZipProgressEventType.Saving_AfterWriteEntry:
            StepArchiveProgress(e);
            break;
        case ZipProgressEventType.Saving_EntryBytesRead:
            StepEntryProgress(e);
            break;
        case ZipProgressEventType.Saving_Completed:
            SaveCompleted();
            break;
        case ZipProgressEventType.Saving_AfterSaveTempArchive:
            // this event only occurs when saving an SFX file
            TempArchiveSaved();
            break;
    }
    if (_saveCanceled)
        e.Cancel = true;
}



private void StepArchiveProgress(SaveProgressEventArgs e)
{
    if (this.progressBar1.InvokeRequired)
    {
        this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e });
    }
    else
    {
        if (!_saveCanceled)
        {
            _nFilesCompleted++;
            this.progressBar1.PerformStep();
            _totalBytesAfterCompress += e.CurrentEntry.CompressedSize;
            _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize;

            // reset the progress bar for the entry:
            this.progressBar2.Value = this.progressBar2.Maximum = 1;

            this.Update();
        }
    }
}


private void StepEntryProgress(SaveProgressEventArgs e)
{
    if (this.progressBar2.InvokeRequired)
    {
        this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e });
    }
    else
    {
        if (!_saveCanceled)
        {
            if (this.progressBar2.Maximum == 1)
            {
                // reset
                Int64 max = e.TotalBytesToTransfer;
                _progress2MaxFactor = 0;
                while (max > System.Int32.MaxValue)
                {
                    max /= 2;
                    _progress2MaxFactor++;
                }
                this.progressBar2.Maximum = (int)max;
                lblStatus.Text = String.Format("{0} of {1} files...({2})",
                    _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName);
            }

             int xferred = e.BytesTransferred >> _progress2MaxFactor;

             this.progressBar2.Value = (xferred >= this.progressBar2.Maximum)
                ? this.progressBar2.Maximum
                : xferred;

             this.Update();
        }
    }
}

private void SaveCompleted()
{
    if (this.lblStatus.InvokeRequired)
    {
        this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted));
    }
    else
    {
        lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.",
            _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress);
         ResetState();
    }
}

private void ResetState()
{
    this.btnCancel.Enabled = false;
    this.btnOk.Enabled = true;
    this.btnOk.Text = "Zip it!";
    this.progressBar1.Value = 0;
    this.progressBar2.Value = 0;
    this.Cursor = Cursors.Default;
    if (!_workerThread.IsAlive)
        _workerThread.Join();
}

Assembly: Ionic.Zip (Module: Ionic.Zip) Version: 1.9.1.8 (1.9.1.8)