C# | Visual Basic | Visual C++ |
public event EventHandler<ZipErrorEventArgs> ZipError
Public Event ZipError As EventHandler(Of ZipErrorEventArgs)
public: event EventHandler<ZipErrorEventArgs^>^ ZipError { void add (EventHandler<ZipErrorEventArgs^>^ value); void remove (EventHandler<ZipErrorEventArgs^>^ value); }
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 Save().
Setting a handler implicitly sets ZipErrorAction to ZipErrorAction.InvokeErrorEvent.
The handler you add applies to all ZipEntry items that are subsequently added to the ZipFile instance. If you set this property after you have added items to the ZipFile, but before you have called Save(), errors that occur while saving those items will not cause the error handler to be invoked.
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.
In the error handler method, you need to set the ZipErrorAction property on the ZipErrorEventArgs.CurrentEntry. This communicates back to DotNetZip what you would like to do with this particular error. Within an error handler, if you set the ZipEntry.ZipErrorAction property on the ZipEntry to ZipErrorAction.InvokeErrorEvent 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 ZipEntry.ZipErrorAction property on the ZipEntry to ZipErrorAction.Throw.) If you set the ZipErrorEventArgs.Cancel to true, the entire Save() will be canceled.
In the case that you use ZipErrorAction.Skip, 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.
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); } }
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