The ZipWriter and ZipReader classes provides events that let you monitor the progress of the Zip archive creation and extraction processes. Three types of events are available, which are described and demonstrated below.
The local header of the file currently being processed.
When the compressed/uncompressed sizes are unknown, UncompressedSize returns -1 and Percent returns 0, and must therefore not be used. This occurs for example with Zip archives created using ZipWriter, because a backwards seek before the compressed data of a file cannot be performed. Consequently, the values for compressed/uncompressed sizes cannot be modified. A Zip application such as WinZip, however, can seek back and write these values. As a result, when reading such an archive, UncompressedSize and Percent return useful values.
The InvalidPassword event
The ZipReader class additionally exposes an InvalidPassword event, which is raised when no password or an invalid password is provided to a password-protected archive. A ZipReaderInvalidPasswordEventArgs object provides the following properties for use in ZipReader's InvalidPassword event handler:
using System.IO;
using Xceed.Zip.ReaderWriter;
//The target Zip archive.
using (FileStream fileStream1 = new FileStream(@"d:\testOutput\test.zip",
FileMode.Create, FileAccess.Write))
{
//Create a ZipWriter object around the stream.
Xceed.Zip.ReaderWriter.ZipWriter zipWriter1 =
new Xceed.Zip.ReaderWriter.ZipWriter(fileStream1);
//Subscribe to the ByteProgression event
zipWriter1.ByteProgression += new
EventHandler<ZipWriterByteProgressionEventArgs>(zipWriter1_ByteProgression);
DirectoryInfo directoryInfo = new DirectoryInfo(@"d:\test\");
if (directoryInfo.Exists)
{
FileInfo[] files = directoryInfo.GetFiles("*.*",
SearchOption.AllDirectories);
foreach (FileInfo file in files)
{
//Create ZipItemLocalHeader for current item and write to archive.
ZipItemLocalHeader zipItemLocalHeader1 = new ZipItemLocalHeader
(file.Name);
zipWriter1.WriteItemLocalHeader(zipItemLocalHeader1);
byte[] buffer = newbyte[1024];
int read = 0;
using (FileStream fs = file.OpenRead())
{
//Read the current item's data
while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
{
//Write the current item's data to the Zip archive
zipWriter1.WriteItemData(buffer, 0, read);
}
}
}
//Close the Zip archive
zipWriter1.CloseZipFile();
Console.WriteLine("Zip archive created.");
}
}
//The ByteProgression event's handler. Demonstrates the use of
//the properties of ZipWriterByteProgressionEventArgs.
staticvoid zipWriter1_ByteProgression(object sender,
ZipWriterByteProgressionEventArgs e)
{
Console.WriteLine("Item {0}: CompressionMethod = {1},
CompressionLevel = {2}.", e.ZipItemLocalHeader.FileName,
e.ZipItemLocalHeader.CompressionMethod,
e.ZipItemLocalHeader.CompressionLevel);
}
Imports System.IO
Imports Xceed.Zip.ReaderWriter
'The target Zip archive.
Using fileStream1 AsNew FileStream("d:\testOutput\test.zip",
FileMode.Create, FileAccess.Write)
'Create a ZipWriter object around the stream.
Dim zipWriter1 AsNew Xceed.Zip.ReaderWriter.ZipWriter(fileStream1)
'Subscribe to the ByteProgression event.
AddHandler zipWriter1.ByteProgression, AddressOfOf
ZipWriterByteProgressionEventArgs
Dim directoryInfo AsNew DirectoryInfo("d:\test\")
If directoryInfo.Exists ThenDim files As FileInfo() = directoryInfo.GetFiles("*.*",
SearchOption.AllDirectories)
ForEach file As FileInfo In files
'Create ZipItemLocalHeader for current item and write to archive.
Dim zipItemLocalHeader1 AsNew ZipItemLocalHeader(file.Name)
zipWriter1.WriteItemLocalHeader(zipItemLocalHeader1)
Dim buffer AsByte() = NewByte(1023){}
Dim read AsInteger = 0
Using fs As FileStream = file.OpenRead()
'Read the current item's data
read = fs.Read(buffer, 0, buffer.Length)
DoWhile (read <> 0)
'Write the current item's data to the Zip archive
zipWriter1.WriteItemData(buffer, 0, read)
read = fs.Read(buffer, 0, buffer.Length)
LoopEndUsingNext file
'Close the Zip archive
zipWriter1.CloseZipFile()
Console.WriteLine("Zip archive created.")
EndIfEndUsing'The ByteProgression event's handler. Demonstrates the use of
'the properties of ZipWriterByteProgressionEventArgs.
SharedSub zipWriter1_ByteProgression(ByVal sender AsObject, ByVal e As ZipWriterByteProgressionEventArgs)
Console.WriteLine("Item {0}: CompressionMethod = {1},
CompressionLevel = {2}.", e.ZipItemLocalHeader.FileName,
e.ZipItemLocalHeader.CompressionMethod,
e.ZipItemLocalHeader.CompressionLevel)
End Sub
Example 2: Using the ByteProgression and InvalidPassword events (ZipReader)
using System.IO;
using Xceed.Zip.ReaderWriter;
//The source Zip archive.
using (FileStream fileStream1 = new FileStream(@"d:\testOutput\test.zip",
FileMode.Open, FileAccess.Read))
{
//Must seek to the beginning of the stream before reading.
fileStream1.Seek(0, SeekOrigin.Begin);
//Create a ZipReader around the stream.
Xceed.Zip.ReaderWriter.ZipReader zipReader1 =
new Xceed.Zip.ReaderWriter.ZipReader(fileStream1);
//Subscribe to the ByteProgression event
zipReader1.ByteProgression +=
new EventHandler<ZipReaderByteProgressionEventArgs>
(zipReader1_ByteProgression);
//Subscribe to the InvalidPassword event
zipReader1.InvalidPassword +=
new EventHandler<ZipReaderInvalidPasswordEventArgs>
(zipReader1_InvalidPassword);
ZipItemLocalHeader zipItemLocalHeader = null;
//Read the local headers until no more are found
while ((zipItemLocalHeader = zipReader1.ReadItemLocalHeader()) != null)
{
byte[] buffer = newbyte[1024];
int read = 0;
//Read the item's data
while ((read = zipReader1.ReadItemData(buffer, 0, buffer.Length)) > 0)
{
//Do something with the data in 'buffer'
}
}
}
//The InvalidPassword event's handler. Demonstrates the use of
//the properties of ZipReaderInvalidPasswordEventArgs.
staticvoid zipReader1_InvalidPassword(object sender,
ZipReaderInvalidPasswordEventArgs e)
{
Console.Write("Enter password for file {0} (<Enter> alone to abort): ",
e.ZipItemLocalHeader.FileName);
string password = Console.ReadLine();
if (string.IsNullOrEmpty(password))
{
//Set Abort to true to abort the read operation.
e.Abort = true;
}
else
{
//Set NewPassword to the provided password. If it is the correct password,
//the read operation will proceed. Otherwise, the InvalidPassword event is
//raised again.
e.NewPassword = password;
}
}
//The ByteProgression event's handler. Demonstrates the use of
//the properties of ZipReaderByteProgressionEventArgs.
staticvoid zipReader1_ByteProgression(object sender,
ZipReaderByteProgressionEventArgs e)
{
if (e.UncompressedSize == -1)
Console.WriteLine("Processing item {0}: {1} bytes processed.",
e.ZipItemLocalHeader.FileName, e.BytesProcessed);
else
{
//UncompressedSize is not -1, so this property and the Percent property
//return useful values.
Console.WriteLine("Processing item {0}: {1} bytes processed ({3}%).
(Uncompressed size = {3}.)",
e.ZipItemLocalHeader.FileName,
e.BytesProcessed,
e.UncompressedSize,
e.Percent);
}
}
Imports System.IO
Imports Xceed.Zip.ReaderWriter
Using fileStream1 AsNew FileStream("d:\testOutput\test.zip",
FileMode.Open, FileAccess.Read)
'Must seek to the beginning of the stream before reading.
fileStream1.Seek(0, SeekOrigin.Begin)
'Create a ZipReader around the stream.
Dim zipReader1 AsNew Xceed.Zip.ReaderWriter.ZipReader(fileStream1)
'Subscribe to the ByteProgression event
AddHandler zipReader1.ByteProgression, AddressOfOf
ZipReaderByteProgressionEventArgs
'Subscribe to the InvalidPassword event
AddHandler zipReader1.InvalidPassword, AddressOfOf
ZipReaderInvalidPasswordEventArgs
Dim zipItemLocalHeader As ZipItemLocalHeader = Nothing'Read the local headers until no more are found
DoWhileNot (zipItemLocalHeader = zipReader1.ReadItemLocalHeader()) IsNothingDim buffer AsByte() = NewByte(1023){}
Dim read AsInteger = 0
'Read the item's data
DoWhile (read = zipReader1.ReadItemData(buffer, 0, buffer.Length)) > 0
'Do something with the data in 'buffer'
LoopLoopEndUsing'The InvalidPassword event's handler. Demonstrates the use of
'the properties of ZipReaderInvalidPasswordEventArgs.
SharedSub zipReader1_InvalidPassword(ByVal sender AsObject, ByVal e As
ZipReaderInvalidPasswordEventArgs)
Console.Write("Enter password for file {0} (<Enter> alone to abort): ",
e.ZipItemLocalHeader.FileName)
Dim password AsString = Console.ReadLine()
'Set Abort to true to abort the read operation.
IfString.IsNullOrEmpty(password) Then
e.Abort = TrueElse'Set NewPassword to the provided password. If it is the correct password,
'the read operation will proceed. Otherwise, the InvalidPassword event is
'raised again.
e.NewPassword = password
EndIfEnd Sub'The ByteProgression event's handler. Demonstrates the use of
'the properties of ZipReaderByteProgressionEventArgs.
SharedSub zipReader1_ByteProgression(ByVal sender AsObject, ByVal e As
ZipReaderByteProgressionEventArgs)
If e.UncompressedSize = -1 Then
Console.WriteLine("Processing item {0}: {1} bytes processed.",
e.ZipItemLocalHeader.FileName, e.BytesProcessed)
Else'UncompressedSize is not -1, so this property and the Percent
'property return useful values.
Console.WriteLine("Processing item {0}: {1} bytes processed
({3}%). (Uncompressed size = {3}.)",
e.ZipItemLocalHeader.FileName,
e.BytesProcessed, e.UncompressedSize, e.Percent)
EndIfEnd Sub