ZIP Tutorial
Applies to: Rebex Total Pack, Rebex ZIP
Table of content
- Namespaces and assemblies
- Simple API - static methods
- ZIP basics - opening and closing a ZIP archive
- Adding files (compressing)
- Extracting files (decompressing)
- Traversal modes
- Deleting files and directories within the archive
- Moving (renaming) files withing the archive
- Listing ZIP archive contents
- Protecting ZIP with password
- Progress info and progress event
- Handling multi-file operation problems
- Compression level
- Advanced optimisation hints
- Used expressions
Namespaces and assemblies
To use the features of Rebex ZIP for .NET described here, you have to reference
the Rebex.Zip.dll and Rebex.Common.dll assemblies in your project.
It contains the ZipArchive and other classes in Rebex.IO.Compression namespace.
In your source files, import the following namespace:
using Rebex.IO.Compression;
Imports Rebex.IO.Compression
using Rebex.IO.Compression;
Imports Rebex.IO.Compression
Simple API - static methods
The ZipArchive class provides a set of static methods.
These can be used to achieve simple actions:
Compression
// add content of the local directory C:\Data\
// to the directory \Data-2010 (within the ZIP archive)
// (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add(@"C:\archive.zip", @"C:\Data\*", @"\Data-2010");
// add all *.TXT files from the local directory C:\Data\
// to the directory \Data-2010 (within the ZIP file)
// (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add(@"C:\archive.zip", @"C:\Data\*.txt", @"\Data-2010");
// add all *.TXT files from the local directory C:\Data\
// to the root of the ZIP file overwriting all already existing files
// (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add(
@"C:\archive.zip",
@"C:\Data\*.txt",
@"\",
TraversalMode.NonRecursive,
TransferMethod.Copy,
ActionOnExistingFiles.OverwriteAll);
' add content of the local directory C:\Data\
' to the directory \Data-2010 (within the ZIP archive)
' (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add("C:\archive.zip", "C:\Data\*", "\Data-2010")
' add all *.TXT files from the local directory C:\Data\
' to the directory \Data-2010 (within the Zip file)
' (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add("C:\archive.zip", "C:\Data\*.txt", "\Data-2010")
' add all *.TXT files from the local directory C:\Data\
' to the root of the Zip file overwriting all already existing files
' (ZIP archive C:\archive.zip doesn't have to exist)
ZipArchive.Add( _
"C:\archive.zip", _
"C:\Data\*.txt", _
"/", _
TraversalMode.NonRecursive, _
TransferMethod.Copy, _
ActionOnExistingFiles.OverwriteAll)
Decompression
// extract whole content of the ZIP archive to the existing local directory C:\Data ZipArchive.ExtractAll(@"C:\archive.zip", @"C:\Data"); // extract whole content of the directory \Data-2010 (within the ZIP file) // to the existing local directory C:\Data ZipArchive.Extract(@"C:\archive.zip", @"\Data-2010\*", @"C:\Data"); // extract all *.TXT files from the directory \Data-2010 (within the ZIP file) // to the existing local directory C:\Data ZipArchive.Extract(@"C:\archive.zip", @"\Data-2010\*.html", @"C:\Data");
' extract whole content of the ZIP archive to the existing local directory C:\Data
ZipArchive.ExtractAll("C:\archive.zip", "C:\Data")
' extract whole content of the directory \Data-2010 (within the ZIP file)
' to the existing local directory C:\Data
ZipArchive.Extract("C:\archive.zip", "\Data-2010\*", "C:\Data")
' extract all *.TXT files from the directory \Data-2010 (within the ZIP file)
' to the existing local directory C:\Data
ZipArchive.Extract("C:\archive.zip", "\Data-2010\*.html", "C:\Data")
Deleting
// deletes all *.TXT files from the root of the ZIP archive ZipArchive.Delete(@"C:\archive.zip", "*.txt", TraversalMode.NonRecursive); // deletes directory \Data-2009 with all of its content ZipArchive.Delete(@"C:\archive.zip", @"\Data-2009", TraversalMode.Recursive);
' deletes all *.TXT files from the root of the ZIP archive
ZipArchive.Delete("C:\archive.zip", "*.txt", TraversalMode.NonRecursive)
' deletes directory \Data-2009 with all of its content
ZipArchive.Delete("C:\archive.zip", "\Data-2009", TraversalMode.Recursive)
If you need more features than those offered by the simple static methods (such as
retrieving a list of files in a ZIP archive or displaying a progress bar) you
will have to open a ZIP archive by creating a new instance of the ZipArchive
class.
ZIP basics - opening and closing a ZIP archive
To open a ZIP archive, simply create a new instance of of the ZipArchive class.
Then use its methods to perform the desired actions.
When you are done with the ZIP archive, call
ZipArchive object's Close method to close the underlying
file (and save pending changes if required). Alternatively, utilize the using
keyword.
Opening a ZIP archive
// open the ZIP archive from an existing file ZipArchive zip = new ZipArchive(@"C:\archive.zip", ArchiveOpenMode.Open); // ... do some work // close the archive zip.Close();
' open the ZIP archive from an existing file
Dim zip As New ZipArchive("C:\archive.zip", ArchiveOpenMode.Open)
' ... do some work
' close the ZIP archive
zip.Close()
Listing the contents of the ZIP archive
Note the use of using keyword here.
// open the ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip"))
{
// get collection of all items in the root of the ZIP archive
ZipItemCollection items = zip.GetItems(@"\", TraversalMode.Recursive);
// sort the collection by name (directories first)
items.Sort();
// display info about each item
foreach (ZipItem item in items)
{
if (item.IsDirectory)
Console.WriteLine("D {0} [{1}]", item.Name, item.LastWriteTime);
else
Console.WriteLine(
"f {0} {1}B [{2}]", item.Name, item.Length, item.LastWriteTime);
}
}
' open the ZIP archive
Using zip As New ZipArchive("C:\archive.zip")
' get collection of all items in the root of the ZIP archive
Dim items = zip.GetItems("/", TraversalMode.Recursive)
' sort the collection by name (directories first)
items.Sort()
' display info about each item
For Each item As ZipItem In items
If item.IsDirectory Then
Console.WriteLine("D {0} [{1}]", item.Name, item.LastWriteTime)
Else
Console.WriteLine( _
"f {0} {1}B [{2}]", item.Name, item.Length, item.LastWriteTime)
End If
Next item
End Using
Adding files (compressing)
To add files into the ZIP archive, use Add or AddFile methods.
The AddFile method only adds a single file. This makes it possible to specify a different file name for
it.
To use the original name, just specify the target directory path with an ending slash instead.
// add 'C:\Data\file.txt' file to the (root of the) ZIP archive zip.AddFile(@"C:\Data\file.txt"); // add local file to the archive directory \Data-2010 // and name the added file "file-01.txt" zip.AddFile(@"C:\Data\file.txt", @"\Data-2010\file-01.txt"); // add local file to the \Data-2010\ archive directory // if the file already exists there and is older, overwrite it // (the ending slash in the archive path indicates that you // actually mean a directory instead of an extension-less file name) zip.AddFile(@"C:\Data\file.txt", @"\Data-2010\", ActionOnExistingFiles.OverwriteOlder);
' add 'C:\Data\file.txt' file to the (root of the) ZIP archive
zip.AddFile("C:\Data\file.txt")
' add local file to the archive directory \Data-2010
' and name the added file "file-01.txt"
zip.AddFile("C:\Data\file.txt", "\Data-2010\file-01.txt")
' add local file to the \Data-2010\ archive directory
' if the file already exists there and is older, overwrite it
' (the ending slash in the archive path indicates that you
' actually mean a directory instead of an extension-less file name)
zip.AddFile("C:\Data\file.txt", "\Data-2010\", ActionOnExistingFiles.OverwriteOlder)
The Add method adds multiple files or directories in a single call.
The first argument specifies a file, a directory or a group of files or directories (see path/mask) to add.
The second argument is the target directory path (in the ZIP archive).
Optional arguments specify various compression options like traversal mode or action
on existing files.
// add all; *.txt files from 'C:\Data'
// to the (root of the) ZIP archive
zip.Add(@"C:\Data\*.txt");
// add all *.txt files from 'C:\Data'
// to the '\Data-2010' directory in the ZIP archive
zip.Add(@"C:\Data\*.txt", @"\Data-2010");
// add the whole content of 'C:\Data'
// to the '\Data-2010' directory in the ZIP archive
// (overwrite all already-existing files)
zip.Add(
@"C:\Data\*",
@"\Data-2010",
TraversalMode.Recursive,
TransferMethod.Copy,
ActionOnExistingFiles.OverwriteAll);
' add all; *.txt files from 'C:\Data'
' to the (root of the) ZIP archive
zip.Add("C:\Data\*.txt")
' add all *.txt files from 'C:\Data'
' to the '\Data-2010' directory in the ZIP archive
zip.Add("C:\Data\*.txt", "\Data-2010")
' add the whole content of 'C:\Data'
' to the '\Data-2010' directory in the ZIP archive
' (overwrite all already-existing files)
zip.Add(
"C:\Data\*", _
"\Data-2010", _
TraversalMode.Recursive, _
TransferMethod.Copy, _
ActionOnExistingFiles.OverwriteAll)
Extracting files (decompressing)
To extract data from a ZIP archive, use Extract, ExtractAll or ExtractFile
methods.
The ExtractFile method only extracts a single file. This makes it possible to specify a different file
name for it.
To use the original name, just specify the target directory path with an ending slash instead.
// extract '\Data-2010\file.txt' file to 'C:\Data\file-01.txt' file zip.ExtractFile(@"\Data-2010\file.txt", @"C:\Data\file-01.txt"); // extract '\Data-2010\file.txt' file to 'C:\Data' directory // if the file already exists there, the file will be extracted to a renamed copy // (the ending slash in the archive path indicates that you // actually mean a directory instead of an extension-less file name) zip.ExtractFile(@"\Data-2010\file.txt", @"C:\Data\", ActionOnExistingFiles.Rename);
' extract '\Data-2010\file.txt' file to 'C:\Data\file-01.txt' file
zip.ExtractFile("\Data-2010\file.txt", "C:\Data\file-01.txt")
' extract '\Data-2010\file.txt' file to 'C:\Data' directory
' if the file already exists there, the file will be extracted to a renamed copy
' (the ending slash in the archive path indicates that you
' actually mean a directory instead of an extension-less file name)
zip.ExtractFile("\Data-2010\file.txt", "C:\Data\", ActionOnExistingFiles.Rename)
The Extract method extracts multiple files or directories in a single call.
The first argument specifies a file, a directory or a group of files and directories (see path/mask) to extract.
The second argument is the target directory path (in the local filesystem).
Optional arguments specify various compression options like traversal mode or action
on existing files.
// extract whole ZIP archive to 'C:\Data' directory
zip.ExtractAll(@"C:\Data");
// extract all *.txt files from '\Data-2010' archive directory
// to 'C:\Data' directory
zip.Extract(@"\Data-2010\*.txt", @"C:\Data");
// extract whole content of '\Data-2010' archive directory
// to 'C:\Data' directory and overwrite all already-existing files
zip.Extract(
@"\Data-2010\*",
@"C:\Data",
TraversalMode.Recursive,
TransferMethod.Copy,
ActionOnExistingFiles.OverwriteAll);
' extract whole ZIP archive to 'C:\Data' directory
zip.ExtractAll("C:\Data")
' extract all *.txt files from '\Data-2010' archive directory
' to 'C:\Data' directory
zip.Extract("\Data-2010\*.txt", "C:\Data")
' extract whole content of '\Data-2010' archive directory
' to 'C:\Data' directory and overwrite all already-existing files
zip.Extract(
"\Data-2010\*", _
"C:\Data", _
TraversalMode.Recursive, _
TransferMethod.Copy, _
ActionOnExistingFiles.OverwriteAll)
The ExtractAll method is a shortcut for extracting the whole content of the ZIP archive to the
specified directory.
Traversal modes
Traversal mode is an optional argument for Add,
Extract and Delete methods.
It specifies whether to include the content of subdirectories in the requested operation, and how to traverse them:
ArchiveTraversalMode
-
ArchiveTraversalMode.NonRecursive- Only compresses files and directories matching the specified path/mask. The content of matched directories is not compressed. -
ArchiveTraversalMode.Recursive- Recursive mode. Processes all files and subdirectories matching the specified path/mask. If the source path is a masked path, files/directories in the first level are matched and if their name matches the specified mask, their whole content is compressed. (For example, source path "C:\Data\text*" compresses all files and directories whose name starts with "text" - any files and subdirectories in the matched directories are also compressed, regardless of their names). -
ArchiveTraversalMode.DeepMatch- Recursive xcopy-like mode. This is similar toRecursivemode, but the mask is applied to files on all levels and all subdirectories are included in the search. (DeepMatchmode can create a lot of empty directories if a wide directory hierarchy is specified but only contains few matching files.)
Deleting files and directories within the archive
To delete a file or a directory in the ZIP archive, use Delete method. Optionally, specify a traversal mode (useful when deleting a whole directory tree).
Another optional argument is a save action - this makes it possible to either rearrange (shrink) the ZIP file to
remove the unused space left by the deleted files.
By default, Delete method does rearrange the ZIP file if needed (ArchiveSaveAction.Auto).
An alternative is to
specify ArchiveSaveAction.None to skip rearranging (shrinking) and perform this operation later
by explicitly calling Save(ArchiveSaveAction.Shrink) method later or
Close(ArchiveSaveAction.Shrink) method when closing the archive.
// delete single file named 'file.txt' zip.DeleteFile(@"\file.txt"); // delete whole '\Data-2007' directory with all subfiles and subdirectories zip.Delete(@"\Data-2007", TraversalMode.Recursive); // delete several files and directories without shrinking (to save time) zip.DeleteFile(@"\file.txt", ArchiveSaveAction.None); zip.Delete(@"\*.jpg", TraversalMode.MatchFilesShallow, ArchiveSaveAction.None); zip.Delete(@"\Data-2008", TraversalMode.Recursive, ArchiveSaveAction.None); // now shrink the archive (remove any unused space) zip.Save(ArchiveSaveAction.Shrink); // delete whole '\Data-2009' directory with all its files and subdirectories, // save any changes and shrink the archive - all in one call zip.Delete(@"\Data-2009", TraversalMode.Recursive, ArchiveSaveAction.Shrink);
' delete single file named 'file.txt'
zip.DeleteFile("\file.txt")
' delete whole '\Data-2007' directory with all subfiles and subdirectories
zip.Delete("\Data-2007", TraversalMode.Recursive)
' delete several files without shrinking (to save time)
zip.DeleteFile("\file.txt", ArchiveSaveAction.None)
zip.Delete("\*.jpg", TraversalMode.MatchFilesShallow, ArchiveSaveAction.None)
zip.Delete("\Data-2008", TraversalMode.Recursive, ArchiveSaveAction.None)
' now shrink the archive (remove any unused space)
zip.Save(ArchiveSaveAction.Shrink)
' delete whole '\Data-2009' directory with all its files and subdirectories,
' save any changes and shrink the archive - all in one call
zip.Delete("\Data-2009", TraversalMode.Recursive, ArchiveSaveAction.Shrink)
Moving (renaming) files withing the archive
To move and rename files or directories in a ZIP archive, use ZipArchive object's Move
method (rename or move) or
ZipItem object's Rename method (rename only).
// get the item object for '\dir\file.txt'
ZipItem item = zip.GetItem(@"\dir\file.txt");
// rename the item (the new path will be '\dir\renamed.txt')
item.Rename("renamed.txt");
// move the '\dir\file.txt' file to '\moved' directory
zip.Move(@"\dir\file.txt", @"\moved\file.txt");
// move the "\dir\file.txt" file to '\moved' directory
// and rename it to 'renamed.txt"
zip.Move(@"\dir\file.txt", @"\moved\renamed.txt");
' get the item object for '\dir\file.txt'
Dim item As ZipItem = zip.GetItem("\dir\file.txt")
' rename the file (the new path will be '\dir\renamed.txt')
item.Rename("renamed.txt")
' move the '\dir\file.txt' file to '\moved' directory
zip.Move("\dir\file.txt", "\moved\file.txt")
' move the "\dir\file.txt" file to '\moved' directory
' and rename it to 'renamed.txt"
zip.Move("\dir\file.txt", "\moved\renamed.txt")
Listing ZIP archive contents
Each file and directory within a ZIP archive (ZipArchive class) is represented by a
ZipItem object
that holds information such as name, compressed/uncompressed length, last modification date, comment, etc.
ZipItem can be retrieved by 2 methods.
-
GetItemmethod orZipArchiveindexer - returns aZipItemobject that represents the specified file or directory (or null/Nothing if it doesn't exist). -
GetItemsmethod - returns a collection ofZipItemobjects matching the specified arguments. (GetItemsreturns a list of files that would be extracted if theExtractmethod with identical arguments was called.)
// get information about the '\Data-2010' directory
ZipItem info1 = zip.GetItem(@"\Data-2010");
// equivalent to the previous call (GetItem method)
ZipItem info2 = zip[@"\Data-2010"];
// get all items (files and directories) in the '\Data-2010' directory
ZipItemCollection items = zip.GetItems(@"\Data-2010\*", TraversalMode.NonRecursive);
// get all items (files and directories) from the 'Data-2010' directory
// including all subdirectories
ZipItemCollection allItems = zip.GetItems(
@"\Data-2010",
TraversalMode.Recursive);
// get all directories whose name starts with 'Data'
ZipItemCollection dataDirectories = zip.GetItems(
@"\Data*",
TraversalMode.NonRecursive,
ArchiveItemTypes.Directories);
// get whole content of all directories whose name starts with 'Data'
ZipItemCollection dataContent = zip.GetItems(
@"\Data*",
TraversalMode.Recursive,
ArchiveItemTypes.All);
// get all .txt files in the archive
ZipItemCollection txtFiles = zip.GetItems(
"*.txt",
TraversalMode.MatchFilesDeep,
ArchiveItemTypes.Files);
' get information about the '\Data-2010' directory
Dim info1 = zip.GetItem("\Data-2010")
' equivalent to the previous call (GetItem method)
Dim info2 = zip("\Data-2010")
' get all items (files and directories) in the '\Data-2010' directory
Dim items = zip.GetItems("\Data-2010\*", TraversalMode.NonRecursive)
' get all items (files and directories) from the '\Data-2010' directory
' including all subdirectories
Dim allItems As ZipItemCollection = zip.GetItems( _
"\Data-2010", _
TraversalMode.Recursive)
' get all directories whose name starts with 'Data'
Dim dataDirectories As ZipItemCollection = zip.GetItems( _
"\Data*", _
TraversalMode.NonRecursive, _
ArchiveItemTypes.Directories)
' get whole content of all directories whose name starts with 'Data'
Dim dataContent As ZipItemCollection = zip.GetItems( _
"\Data*", _
TraversalMode.Recursive, _
ArchiveItemTypes.All)
' get all .txt files in the archive
Dim txtFiles As ZipItemCollection = zip.GetItems( _
"*.txt", _
TraversalMode.MatchFilesDeep, _
ArchiveItemTypes.Files)
Protecting ZIP with password
To encrypt files, simply set the Password property of the ZipArchive class first.
From the moment you set the Password newly added files are encrypted until you unset the
Password.
Unset means assign a null reference (Nothing in Visual Basic) to the Password property.
Note that setting the Password property to an empty string causes the files to be encrypted with the
empty password.
To use other than default encryption algorithm, use the EncryptionAlgorithm property of the
ZipArchive class.
Please note that we also support Zip 2.0 (traditional PKWARE encryption) to enable compatibility with old legacy
applications,
but this algorithm is considered weak by today's standards.
// create new ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip", ArchiveOpenMode.Create))
{
// set the Password first
zip.Password = "PASSword#123";
// optionally change the default Encryption algorithm
zip.EncryptionAlgorithm = EncryptionAlgorithm.Aes128;
// now add files
zip.Add(@"C:\Data");
}
' create new ZIP archive
Using zip As New ZipArchive("C:\archive.zip", ArchiveOpenMode.Create)
' set the Password first
zip.Password = "PASSword#123"
' optionally change the default Encryption algorithm
zip.EncryptionAlgorithm = EncryptionAlgorithm.Aes128
' now add files
zip.Add("C:\Data")
End Using
Decryption process is very similar, but you can choose from two ways. Either set the Password property
of the ZipArchive class
or register the PasswordRequired event. The event is fired when you are trying to extract encrypted
file, but you didn't specify a password
or when the specified password is invalid.
// open a ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip", ArchiveOpenMode.Open))
{
// set the Password first
zip.Password = "PASSword#123";
// extract whole ZIP content
zip.ExtractAll(@"C:\Data");
}
' open a ZIP archive
Using zip As New ZipArchive("C:\archive.zip", ArchiveOpenMode.Open)
' set the Password first
zip.Password = "PASSword#123"
' extract whole ZIP content
zip.ExtractAll("C:\Data")
End Using
Real scenario decryption process using PasswordRequired event is shown in the
ZIP Extractor sample.
// open a ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip", ArchiveOpenMode.Open))
{
// set the PasswordRequired event first
zip.PasswordRequired +=
new EventHandler<ZipPasswordRequiredEventArgs>(zip_PasswordRequired);
// extract whole ZIP content
zip.ExtractAll(@"C:\Data");
}
// ...
' open a ZIP archive
Using zip As New ZipArchive("C:\archive.zip", ArchiveOpenMode.Open)
' set the PasswordRequired event first
AddHandler zip.PasswordRequired, AddressOf zip_PasswordRequired
' extract whole ZIP content
zip.ExtractAll("C:\Data")
End Using
' ...
Progress info and progress event
To get informed about the progress of the current compress/decompress operations, just register the
ProgressChanged event.
When using multi-file operations like Add, Extract or
ExtractAll methods,
the ProgressChanged event handler will receive useful information: currently processed file, its
length, total progress, number of bytes processed, etc.
When only processing a single file using AddFile or ExtractFile method, the
ProgressChanged event handler
will still receive a subset of the above-mentioned information (like CurrentFileProcessedPercentage).
// register the Progress event
zip.ProgressChanged +=
new EventHandler<ZipProgressChangedEventArgs>(zip_ProgressChanged);
// extract all files, this will fire the Progress event
zip.ExtractAll(@"C:\Data");
// ...
' register the Progress event
AddHandler zip.ProgressChanged, AddressOf zip_ProgressChanged
' extract all files, this will fire the Progress event
zip.ExtractAll("C:\Data")
' ...
Handling multi-file operation problems
With multi-file operations, things can occasionally go wrong due to unforeseen problems.
To be informed about such problems, just register the ProblemDetected event.
When things go wrong (for example a file we are trying to extract already exists in the target folder), the the
ProblemDetected event
is raised and it can be used to specify the desired action to take.
The type of the problem is determined using the event-argument's ProblemType property. This describes
what is going on.
Exception property contains further information - it's actually an exception that would be thrown
unless a different action
is choosen. Use IsActionPossible method (or PossibleActions flag property) to determine
which actions are possible,
and specify the desired action using the Action property.
// register the ProblemDetected event
zip.ProblemDetected +=
new EventHandler<ZipProblemDetectedEventArgs>(zip_ProblemDetected);
// extract all files, this will fire the ProblemDetected event if any problem occurs
zip.ExtractAll(@"C:\Data");
// ...
' register the Progress event
AddHandler zip.ProblemDetected, AddressOf zip_ProblemDetected
' extract all files, this will fire the ProblemDetected event if any problem occurs
zip.ExtractAll("C:\Data")
' ...
Compression level
When compressing data, you can choose between compression speed and quality using the ZipArchive
object's CompressionLevel property.
Levels from 0 to 9 are supported:
- 0 = No compression, but very fast.
- 1 = The fastest compression, but the worst compression ratio.
- 6 = Default compression, a compromise between speed and compression ratio.
- 9 = Best compression ratio, but the slowest.
// open a ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip"))
{
// get files in the 'C:\Data' directory
string[] files = Directory.GetFiles(@"C:\Data");
// choose compression level for each file according to the file type
foreach (string file in files)
{
switch (Path.GetExtension(file))
{
// don't waste time with already-compressed files
case ".jpg":
case ".gif":
case ".mp3":
zip.CompressionLevel = 0;
zip.AddFile(file);
break;
// use best compression for all other files
default:
zip.CompressionLevel = 9;
zip.AddFile(file);
break;
}
}
}
' open a ZIP archive
Using zip As New ZipArchive("C:\archive.zip")
' get files in the 'C:\Data' directory
Dim files = Directory.GetFiles("C:\Data")
' choose compression level for each file according to the file type
For Each File As String In files
Select Case Path.GetExtension(File)
' don't waste time with already-compressed files
Case ".jpg", ".gif", ".mp3"
zip.CompressionLevel = 0
zip.AddFile(File)
' use best compression for all other files
Case Else
zip.CompressionLevel = 9
zip.AddFile(File)
End Select
Next File
End Using
Advanced optimisation hints
The ZipArchive class exposes the ArchiveSaveMode property which is set to
ArchiveSaveMode.Immediate by default.
This value causes all changes made to the ZIP archive to be saved to the underlying stream immediately.
Although this makes the ZipArchive class very easy to use, it can cause a noticeable slow-down when
performing a lot of "single" operations.
For example, updating the LastWriteTime property of 1000s of files will cause the full ZIP archive
central-directory-structure to be saved
1000s of times again and again as well.
To avoid this, switch the ZipArchive object to ArchiveSaveMode.Delayed mode, perform the
"single" operations and explicitly
call the Save method to save all changes once.
In a similar fashion, Delete method called with ArchiveSaveAction.Auto argument rearranges
(shrinks) the ZIP archive
in ArchiveSaveMode.Immediate mode. If you need to perform many single Delete operations, switching to
ArchiveSaveMode.Delayed mode
temporarily might result in a great speed boost.
// open a ZIP archive
using (ZipArchive zip = new ZipArchive(@"C:\archive.zip"))
{
// turn off "immediately saving mode"
zip.SaveMode = ArchiveSaveMode.Delayed;
// get files in the 'C:\Data' directory
string[] files = Directory.GetFiles(@"C:\Data");
foreach (string file in files)
{
string filename = Path.GetFileName(file);
zip.AddFile(file, filename);
// set comment and last write time for the newly-added file
zip[filename].Comment = "Comment for file " + filename;
zip[filename].LastWriteTime = DateTime.Now;
}
// save all changes (comments and write times) made earlier
// (this needs to be called before turning on auto-save again)
zip.Save();
// turn on 'auto-save' mode
zip.SaveMode = ArchiveSaveMode.Immediate;
// ... do some work with ZIP archive in "immediately saving mode"
}
' open a ZIP archive
Using zip As New ZipArchive("C:\archive.zip")
' turn off "immediately saving mode"
zip.SaveMode = ArchiveSaveMode.Delayed
' get files in the 'C:\Data' directory
Dim files = Directory.GetFiles("C:\Data")
For Each file As String In files
Dim filename As String = Path.GetFileName(file)
zip.AddFile(file, filename)
' set comment and last write time for the newly-added file
zip(filename).Comment = "Comment for file " + filename
zip(filename).LastWriteTime = DateTime.Now
Next file
' save all changes (comments and write times) made earlier
' (this needs to be called before turning on auto-save again)
zip.Save()
'turn on 'auto-save' mode
zip.SaveMode = ArchiveSaveMode.Immediate
' ... do some work with ZIP archive in "immediately saving mode"
End Using
Used expressions
- Mask, masked path or path/mask is a path which contains wildcards ('*' or '?'). The wildcards are only allowed at the last level of the path ("C:\Data\*.txt" is a valid path mask, "C:\Data\*\bin" is not).
- Multi-file operations are methods which process (compress, decompress or delete) more files in a single call.
Back to tutorial list...