More .NET libraries
-
Rebex Total Pack
All Rebex .NET libraries together
Back to feature list...
Advanced ZIP features
On this page:
- ZIP archive opening modes
- Setting comments
- Setting compression level
- Setting compression method
- Protecting ZIP archives with password
- Encrypting existing ZIP archives
- Extracting encrypted ZIP archives
- Multithreading support
- Archive shrinking
- Large file support (ZIP64™)
- Enhanced deflate (Deflate64™)
- Delayed mode
- Integrity checking
- Deflate, ZLIB and GZIP streams
ZIP archive opening modes
When initializing ZipArchive
from a file, use ArchiveOpenMode
and ArchiveAccessMode
parameters
to specify how to open or create the ZIP file:
// open existing ZIP archive in read-only mode var zip = new ZipArchive( @"C:\MyData\archive.zip", ArchiveOpenMode.Open, ArchiveAccessMode.Read);
When using a ZipArchive
initalized from a stream, closing the ZipArchive
will close the underlying stream as well be default.
To change this behavior, specify ArchiveStreamCloseMode.LeaveOpen
.
// do not close the stream when ZipArchive is closed var zip = new ZipArchive(stream, ArchiveStreamCloseMode.LeaveOpen);
Setting comments
To get or set a ZIP archive comment, use the ZipArchive.Comment
property.
To get or set a comment of an item (such as a file) in the ZIP archive, use the ZipItem.Comment
property.
// add comment to the ZIP archive zip.Comment = "This archive contains financial data for the year 2000."; // add comment to a particular file zip["orders-2000-01.txt"].Comment = "This file contains list of orders from January 2000.";
Note: The maximum length of a comment is limited to 65,535 bytes.
ZipItem
comments are encoded using UTF-8 character set.
ZipArchive
comments are encoded using IBM Code Page 437 character set.
Setting compression level
To set compression level, use ZipArchive.CompressionLevel
property.
It accepts values from 0 to 9, where 0 means no compression (fastest) and 9 means best compression (slowest).
The default compression level is 6 (medium compression and speed).
// specify best (and slowest) compression (default is 6) zip.CompressionLevel = 9;
Note: CompressionLevel
only applies to newly added files.
Setting compression method
To specify compression method, use ZipArchive.CompressionMethod
property.
// specify enhanced deflate - compatible with Deflate64(tm) by PKWARE, Inc. zip.CompressionMethod = CompressionMethod.EnhancedDeflate;
Note: CompressionMethod
only applies to newly added files.
Protecting ZIP archives with password
To protect archived data from being extracted by unauthorised users, use ZipArchive.Password
property.
WinZip® AE-2 encryption algorithm is used by default.
To specify a different encryption algorithm, use ZipArchive.EncryptionAlgorithm
property.
// set password first zip.Password = "SecretPassword"; // specify encryption algorithm (default is AES-256) zip.EncryptionAlgorithm = EncryptionAlgorithm.Aes128; // add some files (they will be encrypted) zip.Add(@"C:\MyData\private\*.*"); // disable encryption for subsequently-added files zip.Password = null; // or set encryption to none zip.EncryptionAlgorithm = EncryptionAlgorithm.None; // add some files (they will not be encrypted) zip.Add(@"C:\MyData\public\*.*");
Note: encryption only applies to newly added files.
Note: We are unable to support the proprietary and patented SES encryption format because its vendor refused to grant us a license. Fortunately, due to licensing issues, most third-party ZIP applications and libraries use WinZip® AE-2 instead.
Note: The ZIP format makes it possible to set a different password for each file. However, this is discouraged because it could confuse users and third-party ZIP applications.
Warning: For compatibility with legacy ZIP archives, we also support traditional PKWARE's ZIP 2.0 encryption
(EncryptionAlgorithm.Zip20
).
However, please be aware that this algorithm is considered very weak and should no longer be used.
WinZip is a registered trademark of Corel Corporation.
Encrypting existing ZIP archives
If you already have a ZIP archive and need to encrypt it with a password, use ZipArchive.Encrypt
method.
This will encrypt the compressed archive files without the need to recompress them.
// encrypt 'archive.zip' using AES-256 encryption algorithm ZipArchive.Encrypt( @"C:\MyData\archive.zip", @"C:\MyData\encrypted-archive.zip", "SecretPassword", EncryptionAlgorithm.Aes256);
Tip: For a reverse process, use ZipArchive.Decrypt
method.
Extracting encrypted ZIP archives
To extract contents of a protected ZIP archive, set ZipArchive.Password
property:
// set the password before extracting zip.Password = "SecretPassword"; // extract all files zip.ExtractAll(@"C:\MyData\Out");
Alternatively, do this in a custom PasswordRequired
event:
// register PasswordRequired event to handle password requests zip.PasswordRequired += (s, e) => { if (e.Reason == ArchivePasswordReason.IncorrectPasswordOrCorruptedData) { Console.WriteLine( "The password for '{0}' is incorrect.", e.ArchiveItemPath); } // ask user for a password Console.WriteLine("Password: "); string password = GetPasswordFromUser(); // set the password e.Password = password; // or set default ZipArchive password to keep using it for subsequent files zip.Password = password; }; // extract all files // (PasswordRequired event will be raised if password is required) zip.ExtractAll(@"C:\MyData\Out");
Multithreading support
ZipArchive
class can utilize multiple threads to improve compression performance.
By default, the number of compressor threads depends on the number of CPU cores and ThreadPool
settings.
however, this can be changed using ZipArchive.Options.CompressorCount
property.
// disable multithreaded compression zip.Options.CompressorCount = 1; // specify preferred number of compressor threads zip.Options.CompressorCount = 4;
Tip: Using more than 4 threads is unlikely to result in any significantly performance enhancement.
Note: Multithreaded compression is not supported on .NET Compact Framework.
Archive shrinking
If the ZIP file contains gaps, calling ZipArchive.Save(ArchiveSaveAction.Shrink)
method will shrink it and remove the gaps.
This is usually needed after deleting files from a ZIP archive in delayed mode:
// register ShrinkProgress event zip.ShrinkProgress += (s, e) => { Console.WriteLine("Shrinking: {0}/{1} {2}%", e.ItemsProcessed, e.ItemsTotal, e.ProgressPercentage); }; // get info of ZIP file (for demo purposes only) var info = new FileInfo(zip.FilePath); // print current ZIP file size Console.WriteLine("Before delete: {0} bytes", info.Length); // disable immediate save to prevent from automatic shrinking zip.SaveMode = ArchiveSaveMode.Delayed; // delete some files (resulting in unused gaps inside the ZIP file) zip.DeleteFile("file1.txt"); zip.DeleteFile("file4.txt"); zip.DeleteFile("file6.txt"); // print current ZIP file size Console.WriteLine("After delete: {0} bytes", new FileInfo(zip.FilePath).Length); // shrink archive to decrease size of final ZIP file zip.Save(ArchiveSaveAction.Shrink); // print current ZIP file size Console.WriteLine("After shrink: {0} bytes", new FileInfo(zip.FilePath).Length);
Large file support (ZIP64™)
The original ZIP format has very low size limits (see table below). However, Rebex ZIP supports the new ZIP64™ format as well, making it possible to surpass these limitations.
Original ZIP | ZIP64™ | |
---|---|---|
Total size of ZIP archive in bytes | 232 - 1 (4 GB) | 264 - 1 (16 EB) |
Uncompressed size of a file in archive | 232 - 1 (4 GB) | 264 - 1 (16 EB) |
Total number of entries in archive | 216 - 1 (65535) | 232 - 1 (4 billion) |
Note: ZIP64™ format is not used by default to maintain wide compatibility. However, it is used automatically when needed.
To change this behavior, use ZipArchive.Options.Zip64Mode
property:
// disable ZIP64(tm) format zip.Options.Zip64Mode = Zip64Mode.Never;
Note: In practice, the maximum file size might be limited by the underlying file system. Check out File systems limits.
Note: Please note that some ZIP tools don't support ZIP64™ format, which can lead to inability to extract ZIP64™ archives (even if smaller than 4 GB).
The ZIP64™ is a registered trademark of PKWARE, Inc.
Enhanced deflate (Deflate64™)
The DEFLATE compression algorithm uses 32 KB sliding window, while Enhanced Deflate uses 64 KB sliding window and allows longer lengths for repetitive segments. Enhance Deflate can lead to big improvements in compression ratios for highly-compressable files.
// specify Enhanced Deflate - compatible with Deflate64(tm) by PKWARE zip.CompressionMethod = CompressionMethod.EnhancedDeflate;
Note: Please note that some ZIP tools don't support Deflate64™ format.
Deflate64™ is a registered trademark of PKWARE, Inc.
Delayed mode
The ZipArchive
object works in auto-save mode by default,
which means that changes made to the ZIP archive are saved to the underlying stream immediately.
This makes the ZipArchive
object easy to use and ensures that the ZIP archive is complete and readable between subsequent actions.
However, this approach can cause noticeable slow-down when performing a lot of certain operations.
For example, when adding or deleting 100 files on-by-one (or just updating their comments),
the updated ZIP archive central-directory-structure would have to be saved during each of those calls, again and again.
To avoid this, set the ZipArchive.SaveMode
property to ArchiveSaveMode.Delayed
,
perform desired operations and explicitly call the Save()
method to commit all changes once.
// turn off 'auto-save' mode zip.SaveMode = ArchiveSaveMode.Delayed; // add files in the 'C:\MyData' directory one-by-one string[] files = Directory.GetFiles(@"C:\MyData"); foreach (string file in files) { zip.AddFile(file); } // save all changes made earlier // (this has to be done before turning on 'auto-save' mode again) zip.Save(); // turn on 'auto-save' mode again zip.SaveMode = ArchiveSaveMode.Immediate;
Note: Deleting files in auto-save mode also causes the ZIP file to be shrinked (to remove the gap in the ZIP archive). when performing many delete operations, switching to delayed mode (even temporarily) might result in substantial speed boost.
Integrity checking
To validate the integrity of a ZIP archive, use CheckIntegrity()
method.
If the result indicats success, the ZipArchive
class is able to parse the ZIP archive structure wthout issues
and provide information about the ZIP items.
// validate ZIP file integrity var result = ZipArchive.CheckIntegrity(@"C:\MyData\archive.zip"); // print the result if (result.Success) { Console.WriteLine("OK - The file structure is valid."); } else { Console.WriteLine("{0} - {1}", result.Status, result.ToString()); }
Note: The CheckIntegrity()
method only validates ZIP archive structure. It does not verify compressed
data and their CRC checksums. Those are verified when extracting files.
Deflate, ZLIB and GZIP streams
Rebex ZIP also features CompressionStream
and DecompressionStream
classes
for working with raw compression/decompression streams using DEFLATE, ZLIB or GZIP formats.
// set compression format according to user selection CompressionFormat format; switch (userSelection) { case "deflate": format = CompressionFormat.Deflate; break; case "zlib": format = CompressionFormat.Zlib; break; case "gzip": format = CompressionFormat.Gzip; break; default: throw new InvalidOperationException("Invalid compression format."); } // prepare output file name string filePath = @"C:\MyData\output." + userSelection; // open stream for writing compressed data using (var output = new CompressionStream(File.Create(filePath), OpenMode.Write, format, CompressionMethod.Deflate)) { using (var writer = new StreamWriter(output)) { writer.WriteLine("Sample text."); } } // open stream for reading decompressed data using (var input = new DecompressionStream(File.OpenRead(filePath), OpenMode.Read, format, CompressionMethod.Deflate)) { using (var reader = new StreamReader(input)) { string data = reader.ReadToEnd(); Console.WriteLine(data); } }
Note: For GZIP format, Rebex ZIP also provides GzipCompressionStream
and GzipDecompressionStream
classes
with additional GZIP-specific features.
Back to feature list...