1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219 |
- // ZipFile.Events.cs
- // ------------------------------------------------------------------
- //
- // Copyright (c) 2008, 2009, 2011 Dino Chiesa .
- // All rights reserved.
- //
- // This code module is part of DotNetZip, a zipfile class library.
- //
- // ------------------------------------------------------------------
- //
- // This code is licensed under the Microsoft Public License.
- // See the file License.txt for the license details.
- // More info on: http://dotnetzip.codeplex.com
- //
- // ------------------------------------------------------------------
- //
- // last saved (in emacs):
- // Time-stamp: <2011-July-09 08:42:35>
- //
- // ------------------------------------------------------------------
- //
- // This module defines the methods for issuing events from the ZipFile class.
- //
- // ------------------------------------------------------------------
- //
- using System;
- using System.IO;
- namespace Ionic.Zip
- {
- public partial class ZipFile
- {
- private string ArchiveNameForEvent
- {
- get
- {
- return (_name != null) ? _name : "(stream)";
- }
- }
- #region Save
- /// <summary>
- /// 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.
- /// </summary>
- ///
- /// <remarks>
- /// <para>
- /// Depending on the particular event, different properties on the <see
- /// cref="SaveProgressEventArgs"/> parameter are set. The following
- /// table summarizes the available EventTypes and the conditions under
- /// which this event handler is invoked with a
- /// <c>SaveProgressEventArgs</c> with the given EventType.
- /// </para>
- ///
- /// <list type="table">
- /// <listheader>
- /// <term>value of EntryType</term>
- /// <description>Meaning and conditions</description>
- /// </listheader>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_Started</term>
- /// <description>Fired when ZipFile.Save() begins.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_BeforeSaveEntry</term>
- /// <description>
- /// Fired within ZipFile.Save(), just before writing data for each
- /// particular entry.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_AfterSaveEntry</term>
- /// <description>
- /// Fired within ZipFile.Save(), just after having finished writing data
- /// for each particular entry.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_Completed</term>
- /// <description>Fired when ZipFile.Save() has completed.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_AfterSaveTempArchive</term>
- /// <description>
- /// 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.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_BeforeRenameTempArchive</term>
- /// <description>
- /// 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.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_AfterRenameTempArchive</term>
- /// <description>
- /// 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.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_AfterCompileSelfExtractor</term>
- /// <description>
- /// Fired after a self-extracting archive has finished compiling. This
- /// EventType is used only within SaveSelfExtractor().
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Saving_BytesRead</term>
- /// <description>
- /// 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.
- /// </description>
- /// </item>
- ///
- /// </list>
- /// </remarks>
- ///
- /// <example>
- ///
- /// This example uses an anonymous method to handle the
- /// SaveProgress event, by updating a progress bar.
- ///
- /// <code lang="C#">
- /// 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);
- /// }
- /// </code>
- /// </example>
- ///
- /// <example>
- /// This example uses a named method as the
- /// <c>SaveProgress</c> event handler, to update the user, in a
- /// console-based application.
- ///
- /// <code lang="C#">
- /// 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);
- /// }
- /// }
- ///
- /// </code>
- ///
- /// <code lang="VB">
- /// 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
- /// </code>
- /// </example>
- ///
- /// <example>
- ///
- /// This is a more complete example of using the SaveProgress
- /// events in a Windows Forms application, with a
- /// Thread object.
- ///
- /// <code lang="C#">
- /// 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();
- /// }
- /// </code>
- ///
- /// </example>
- ///
- /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
- public event EventHandler<SaveProgressEventArgs> SaveProgress;
- internal bool OnSaveBlock(ZipEntry entry, Int64 bytesXferred, Int64 totalBytesToXfer)
- {
- EventHandler<SaveProgressEventArgs> sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
- bytesXferred, totalBytesToXfer);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- return _saveOperationCanceled;
- }
- private void OnSaveEntry(int current, ZipEntry entry, bool before)
- {
- EventHandler<SaveProgressEventArgs> sp = SaveProgress;
- if (sp != null)
- {
- var e = new SaveProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, entry);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
- private void OnSaveEvent(ZipProgressEventType eventFlavor)
- {
- EventHandler<SaveProgressEventArgs> sp = SaveProgress;
- if (sp != null)
- {
- var e = new SaveProgressEventArgs(ArchiveNameForEvent, eventFlavor);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
- private void OnSaveStarted()
- {
- EventHandler<SaveProgressEventArgs> sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.Started(ArchiveNameForEvent);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
- private void OnSaveCompleted()
- {
- EventHandler<SaveProgressEventArgs> sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.Completed(ArchiveNameForEvent);
- sp(this, e);
- }
- }
- #endregion
- #region Read
- /// <summary>
- /// An event handler invoked before, during, and after the reading of a zip archive.
- /// </summary>
- ///
- /// <remarks>
- /// <para>
- /// Depending on the particular event being signaled, different properties on the
- /// <see cref="ReadProgressEventArgs"/> parameter are set. The following table
- /// summarizes the available EventTypes and the conditions under which this
- /// event handler is invoked with a <c>ReadProgressEventArgs</c> with the given EventType.
- /// </para>
- ///
- /// <list type="table">
- /// <listheader>
- /// <term>value of EntryType</term>
- /// <description>Meaning and conditions</description>
- /// </listheader>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Reading_Started</term>
- /// <description>Fired just as ZipFile.Read() begins. Meaningful properties: ArchiveName.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Reading_Completed</term>
- /// <description>Fired when ZipFile.Read() has completed. Meaningful properties: ArchiveName.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Reading_ArchiveBytesRead</term>
- /// <description>Fired while reading, updates the number of bytes read for the entire archive.
- /// Meaningful properties: ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Reading_BeforeReadEntry</term>
- /// <description>Indicates an entry is about to be read from the archive.
- /// Meaningful properties: ArchiveName, EntriesTotal.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Reading_AfterReadEntry</term>
- /// <description>Indicates an entry has just been read from the archive.
- /// Meaningful properties: ArchiveName, EntriesTotal, CurrentEntry.
- /// </description>
- /// </item>
- ///
- /// </list>
- /// </remarks>
- ///
- /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
- public event EventHandler<ReadProgressEventArgs> ReadProgress;
- private void OnReadStarted()
- {
- EventHandler<ReadProgressEventArgs> rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.Started(ArchiveNameForEvent);
- rp(this, e);
- }
- }
- private void OnReadCompleted()
- {
- EventHandler<ReadProgressEventArgs> rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.Completed(ArchiveNameForEvent);
- rp(this, e);
- }
- }
- internal void OnReadBytes(ZipEntry entry)
- {
- EventHandler<ReadProgressEventArgs> rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.ByteUpdate(ArchiveNameForEvent,
- entry,
- ReadStream.Position,
- LengthOfReadStream);
- rp(this, e);
- }
- }
- internal void OnReadEntry(bool before, ZipEntry entry)
- {
- EventHandler<ReadProgressEventArgs> rp = ReadProgress;
- if (rp != null)
- {
- ReadProgressEventArgs e = (before)
- ? ReadProgressEventArgs.Before(ArchiveNameForEvent, _entries.Count)
- : ReadProgressEventArgs.After(ArchiveNameForEvent, entry, _entries.Count);
- rp(this, e);
- }
- }
- private Int64 _lengthOfReadStream = -99;
- private Int64 LengthOfReadStream
- {
- get
- {
- if (_lengthOfReadStream == -99)
- {
- _lengthOfReadStream = (_ReadStreamIsOurs)
- ? SharedUtilities.GetFileLength(_name)
- : -1L;
- }
- return _lengthOfReadStream;
- }
- }
- #endregion
- #region Extract
- /// <summary>
- /// An event handler invoked before, during, and after extraction of
- /// entries in the zip archive.
- /// </summary>
- ///
- /// <remarks>
- /// <para>
- /// Depending on the particular event, different properties on the <see
- /// cref="ExtractProgressEventArgs"/> parameter are set. The following
- /// table summarizes the available EventTypes and the conditions under
- /// which this event handler is invoked with a
- /// <c>ExtractProgressEventArgs</c> with the given EventType.
- /// </para>
- ///
- /// <list type="table">
- /// <listheader>
- /// <term>value of EntryType</term>
- /// <description>Meaning and conditions</description>
- /// </listheader>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_BeforeExtractAll</term>
- /// <description>
- /// Set when ExtractAll() begins. The ArchiveName, Overwrite, and
- /// ExtractLocation properties are meaningful.</description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_AfterExtractAll</term>
- /// <description>
- /// Set when ExtractAll() has completed. The ArchiveName, Overwrite,
- /// and ExtractLocation properties are meaningful.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_BeforeExtractEntry</term>
- /// <description>
- /// Set when an Extract() on an entry in the ZipFile has begun.
- /// Properties that are meaningful: ArchiveName, EntriesTotal,
- /// CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_AfterExtractEntry</term>
- /// <description>
- /// Set when an Extract() on an entry in the ZipFile has completed.
- /// Properties that are meaningful: ArchiveName, EntriesTotal,
- /// CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_EntryBytesWritten</term>
- /// <description>
- /// Set within a call to Extract() on an entry in the ZipFile, as data
- /// is extracted for the entry. Properties that are meaningful:
- /// ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
- /// </description>
- /// </item>
- ///
- /// <item>
- /// <term>ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite</term>
- /// <description>
- /// Set within a call to Extract() on an entry in the ZipFile, when the
- /// extraction would overwrite an existing file. This event type is used
- /// only when <c>ExtractExistingFileAction</c> on the <c>ZipFile</c> or
- /// <c>ZipEntry</c> is set to <c>InvokeExtractProgressEvent</c>.
- /// </description>
- /// </item>
- ///
- /// </list>
- ///
- /// </remarks>
- ///
- /// <example>
- /// <code>
- /// private static bool justHadByteUpdate = false;
- /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
- /// {
- /// if(e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
- /// {
- /// 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;
- /// }
- /// else if(e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
- /// {
- /// if (justHadByteUpdate)
- /// Console.WriteLine();
- /// Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName);
- /// justHadByteUpdate= false;
- /// }
- /// }
- ///
- /// public static ExtractZip(string zipToExtract, string directory)
- /// {
- /// string TargetDirectory= "extract";
- /// using (var zip = ZipFile.Read(zipToExtract)) {
- /// zip.ExtractProgress += ExtractProgress;
- /// foreach (var e in zip1)
- /// {
- /// e.Extract(TargetDirectory, true);
- /// }
- /// }
- /// }
- ///
- /// </code>
- /// <code lang="VB">
- /// Public Shared Sub Main(ByVal args As String())
- /// Dim ZipToUnpack As String = "C1P3SML.zip"
- /// Dim TargetDir As String = "ExtractTest_Extract"
- /// Console.WriteLine("Extracting file {0} to {1}", ZipToUnpack, TargetDir)
- /// Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)
- /// AddHandler zip1.ExtractProgress, AddressOf MyExtractProgress
- /// Dim e As ZipEntry
- /// For Each e In zip1
- /// e.Extract(TargetDir, True)
- /// Next
- /// End Using
- /// End Sub
- ///
- /// Private Shared justHadByteUpdate As Boolean = False
- ///
- /// Public Shared Sub MyExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
- /// If (e.EventType = ZipProgressEventType.Extracting_EntryBytesWritten) Then
- /// If ExtractTest.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)))
- /// ExtractTest.justHadByteUpdate = True
- /// ElseIf (e.EventType = ZipProgressEventType.Extracting_BeforeExtractEntry) Then
- /// If ExtractTest.justHadByteUpdate Then
- /// Console.WriteLine
- /// End If
- /// Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName)
- /// ExtractTest.justHadByteUpdate = False
- /// End If
- /// End Sub
- /// </code>
- /// </example>
- ///
- /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
- public event EventHandler<ExtractProgressEventArgs> ExtractProgress;
- private void OnExtractEntry(int current, bool before, ZipEntry currentEntry, string path)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = new ExtractProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, currentEntry, path);
- ep(this, e);
- if (e.Cancel)
- _extractOperationCanceled = true;
- }
- }
- // Can be called from within ZipEntry._ExtractOne.
- internal bool OnExtractBlock(ZipEntry entry, Int64 bytesWritten, Int64 totalBytesToWrite)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = ExtractProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
- bytesWritten, totalBytesToWrite);
- ep(this, e);
- if (e.Cancel)
- _extractOperationCanceled = true;
- }
- return _extractOperationCanceled;
- }
- // Can be called from within ZipEntry.InternalExtract.
- internal bool OnSingleEntryExtract(ZipEntry entry, string path, bool before)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = (before)
- ? ExtractProgressEventArgs.BeforeExtractEntry(ArchiveNameForEvent, entry, path)
- : ExtractProgressEventArgs.AfterExtractEntry(ArchiveNameForEvent, entry, path);
- ep(this, e);
- if (e.Cancel)
- _extractOperationCanceled = true;
- }
- return _extractOperationCanceled;
- }
- internal bool OnExtractExisting(ZipEntry entry, string path)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = ExtractProgressEventArgs.ExtractExisting(ArchiveNameForEvent, entry, path);
- ep(this, e);
- if (e.Cancel)
- _extractOperationCanceled = true;
- }
- return _extractOperationCanceled;
- }
- private void OnExtractAllCompleted(string path)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = ExtractProgressEventArgs.ExtractAllCompleted(ArchiveNameForEvent,
- path );
- ep(this, e);
- }
- }
- private void OnExtractAllStarted(string path)
- {
- EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
- if (ep != null)
- {
- var e = ExtractProgressEventArgs.ExtractAllStarted(ArchiveNameForEvent,
- path );
- ep(this, e);
- }
- }
- #endregion
- #region Add
- /// <summary>
- /// An event handler invoked before, during, and after Adding entries to a zip archive.
- /// </summary>
- ///
- /// <remarks>
- /// Adding a large number of entries to a zip file can take a long
- /// time. For example, when calling <see cref="AddDirectory(string)"/> on a
- /// directory that contains 50,000 files, it could take 3 minutes or so.
- /// This event handler allws an application to track the progress of the Add
- /// operation, and to optionally cancel a lengthy Add operation.
- /// </remarks>
- ///
- /// <example>
- /// <code lang="C#">
- ///
- /// int _numEntriesToAdd= 0;
- /// int _numEntriesAdded= 0;
- /// void AddProgressHandler(object sender, AddProgressEventArgs e)
- /// {
- /// switch (e.EventType)
- /// {
- /// case ZipProgressEventType.Adding_Started:
- /// Console.WriteLine("Adding files to the zip...");
- /// break;
- /// case ZipProgressEventType.Adding_AfterAddEntry:
- /// _numEntriesAdded++;
- /// Console.WriteLine(String.Format("Adding file {0}/{1} :: {2}",
- /// _numEntriesAdded, _numEntriesToAdd, e.CurrentEntry.FileName));
- /// break;
- /// case ZipProgressEventType.Adding_Completed:
- /// Console.WriteLine("Added all files");
- /// break;
- /// }
- /// }
- ///
- /// void CreateTheZip()
- /// {
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// zip.AddProgress += AddProgressHandler;
- /// zip.AddDirectory(System.IO.Path.GetFileName(DirToZip));
- /// zip.Save(ZipFileToCreate);
- /// }
- /// }
- ///
- /// </code>
- ///
- /// <code lang="VB">
- ///
- /// Private Sub AddProgressHandler(ByVal sender As Object, ByVal e As AddProgressEventArgs)
- /// Select Case e.EventType
- /// Case ZipProgressEventType.Adding_Started
- /// Console.WriteLine("Adding files to the zip...")
- /// Exit Select
- /// Case ZipProgressEventType.Adding_AfterAddEntry
- /// Console.WriteLine(String.Format("Adding file {0}", e.CurrentEntry.FileName))
- /// Exit Select
- /// Case ZipProgressEventType.Adding_Completed
- /// Console.WriteLine("Added all files")
- /// Exit Select
- /// End Select
- /// End Sub
- ///
- /// Sub CreateTheZip()
- /// Using zip as ZipFile = New ZipFile
- /// AddHandler zip.AddProgress, AddressOf AddProgressHandler
- /// zip.AddDirectory(System.IO.Path.GetFileName(DirToZip))
- /// zip.Save(ZipFileToCreate);
- /// End Using
- /// End Sub
- ///
- /// </code>
- ///
- /// </example>
- ///
- /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
- /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
- public event EventHandler<AddProgressEventArgs> AddProgress;
- private void OnAddStarted()
- {
- EventHandler<AddProgressEventArgs> ap = AddProgress;
- if (ap != null)
- {
- var e = AddProgressEventArgs.Started(ArchiveNameForEvent);
- ap(this, e);
- if (e.Cancel) // workitem 13371
- _addOperationCanceled = true;
- }
- }
- private void OnAddCompleted()
- {
- EventHandler<AddProgressEventArgs> ap = AddProgress;
- if (ap != null)
- {
- var e = AddProgressEventArgs.Completed(ArchiveNameForEvent);
- ap(this, e);
- }
- }
- internal void AfterAddEntry(ZipEntry entry)
- {
- EventHandler<AddProgressEventArgs> ap = AddProgress;
- if (ap != null)
- {
- var e = AddProgressEventArgs.AfterEntry(ArchiveNameForEvent, entry, _entries.Count);
- ap(this, e);
- if (e.Cancel) // workitem 13371
- _addOperationCanceled = true;
- }
- }
- #endregion
- #region Error
- /// <summary>
- /// An event that is raised when an error occurs during open or read of files
- /// while saving a zip archive.
- /// </summary>
- ///
- /// <remarks>
- /// <para>
- /// Errors can occur as a file is being saved to the zip archive. For
- /// example, the File.Open may fail, or a File.Read may fail, because of
- /// lock conflicts or other reasons. If you add a handler to this event,
- /// you can handle such errors in your own code. If you don't add a
- /// handler, the library will throw an exception if it encounters an I/O
- /// error during a call to <c>Save()</c>.
- /// </para>
- ///
- /// <para>
- /// Setting a handler implicitly sets <see cref="ZipFile.ZipErrorAction"/> to
- /// <c>ZipErrorAction.InvokeErrorEvent</c>.
- /// </para>
- ///
- /// <para>
- /// The handler you add applies to all <see cref="ZipEntry"/> items that are
- /// subsequently added to the <c>ZipFile</c> instance. If you set this
- /// property after you have added items to the <c>ZipFile</c>, but before you
- /// have called <c>Save()</c>, errors that occur while saving those items
- /// will not cause the error handler to be invoked.
- /// </para>
- ///
- /// <para>
- /// If you want to handle any errors that occur with any entry in the zip
- /// file using the same error handler, then add your error handler once,
- /// before adding any entries to the zip archive.
- /// </para>
- ///
- /// <para>
- /// In the error handler method, you need to set the <see
- /// cref="ZipEntry.ZipErrorAction"/> property on the
- /// <c>ZipErrorEventArgs.CurrentEntry</c>. This communicates back to
- /// DotNetZip what you would like to do with this particular error. Within
- /// an error handler, if you set the <c>ZipEntry.ZipErrorAction</c> property
- /// on the <c>ZipEntry</c> to <c>ZipErrorAction.InvokeErrorEvent</c> or if
- /// you don't set it at all, the library will throw the exception. (It is the
- /// same as if you had set the <c>ZipEntry.ZipErrorAction</c> property on the
- /// <c>ZipEntry</c> to <c>ZipErrorAction.Throw</c>.) If you set the
- /// <c>ZipErrorEventArgs.Cancel</c> to true, the entire <c>Save()</c> will be
- /// canceled.
- /// </para>
- ///
- /// <para>
- /// In the case that you use <c>ZipErrorAction.Skip</c>, implying that
- /// you want to skip the entry for which there's been an error, DotNetZip
- /// tries to seek backwards in the output stream, and truncate all bytes
- /// written on behalf of that particular entry. This works only if the
- /// output stream is seekable. It will not work, for example, when using
- /// ASPNET's Response.OutputStream.
- /// </para>
- ///
- /// </remarks>
- ///
- /// <example>
- ///
- /// This example shows how to use an event handler to handle
- /// errors during save of the zip file.
- /// <code lang="C#">
- ///
- /// public static void MyZipError(object sender, ZipErrorEventArgs e)
- /// {
- /// Console.WriteLine("Error saving {0}...", e.FileName);
- /// Console.WriteLine(" Exception: {0}", e.exception);
- /// ZipEntry entry = e.CurrentEntry;
- /// string response = null;
- /// // Ask the user whether he wants to skip this error or not
- /// do
- /// {
- /// Console.Write("Retry, Skip, Throw, or Cancel ? (R/S/T/C) ");
- /// response = Console.ReadLine();
- /// Console.WriteLine();
- ///
- /// } while (response != null &&
- /// response[0]!='S' && response[0]!='s' &&
- /// response[0]!='R' && response[0]!='r' &&
- /// response[0]!='T' && response[0]!='t' &&
- /// response[0]!='C' && response[0]!='c');
- ///
- /// e.Cancel = (response[0]=='C' || response[0]=='c');
- ///
- /// if (response[0]=='S' || response[0]=='s')
- /// entry.ZipErrorAction = ZipErrorAction.Skip;
- /// else if (response[0]=='R' || response[0]=='r')
- /// entry.ZipErrorAction = ZipErrorAction.Retry;
- /// else if (response[0]=='T' || response[0]=='t')
- /// entry.ZipErrorAction = ZipErrorAction.Throw;
- /// }
- ///
- /// public void SaveTheFile()
- /// {
- /// string directoryToZip = "fodder";
- /// string directoryInArchive = "files";
- /// string zipFileToCreate = "Archive.zip";
- /// using (var zip = new ZipFile())
- /// {
- /// // set the event handler before adding any entries
- /// zip.ZipError += MyZipError;
- /// zip.AddDirectory(directoryToZip, directoryInArchive);
- /// zip.Save(zipFileToCreate);
- /// }
- /// }
- /// </code>
- ///
- /// <code lang="VB">
- /// Private Sub MyZipError(ByVal sender As Object, ByVal e As Ionic.Zip.ZipErrorEventArgs)
- /// ' At this point, the application could prompt the user for an action to take.
- /// ' But in this case, this application will simply automatically skip the file, in case of error.
- /// Console.WriteLine("Zip Error, entry {0}", e.CurrentEntry.FileName)
- /// Console.WriteLine(" Exception: {0}", e.exception)
- /// ' set the desired ZipErrorAction on the CurrentEntry to communicate that to DotNetZip
- /// e.CurrentEntry.ZipErrorAction = Zip.ZipErrorAction.Skip
- /// End Sub
- ///
- /// Public Sub SaveTheFile()
- /// Dim directoryToZip As String = "fodder"
- /// Dim directoryInArchive As String = "files"
- /// Dim zipFileToCreate as String = "Archive.zip"
- /// Using zipArchive As ZipFile = New ZipFile
- /// ' set the event handler before adding any entries
- /// AddHandler zipArchive.ZipError, AddressOf MyZipError
- /// zipArchive.AddDirectory(directoryToZip, directoryInArchive)
- /// zipArchive.Save(zipFileToCreate)
- /// End Using
- /// End Sub
- ///
- /// </code>
- /// </example>
- ///
- /// <seealso cref="Ionic.Zip.ZipFile.ZipErrorAction"/>
- public event EventHandler<ZipErrorEventArgs> ZipError;
- internal bool OnZipErrorSaving(ZipEntry entry, Exception exc)
- {
- if (ZipError != null)
- {
- lock (LOCK)
- {
- var e = ZipErrorEventArgs.Saving(this.Name, entry, exc);
- ZipError(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
- return _saveOperationCanceled;
- }
- #endregion
- }
- }
|