A Java library for zip files and streams
net.lingala.zip4j
for rating Zip4j as the best Java library for zip files [[1][1], [2][2], [3][3], [4][4]]. It has encouraged me to
bring this project to life again after a gap of several years. I tried to add some of the important features that
were requested over this time, and also made the API much more neater. The newer version (> 2.0.0) now supports streams,
which was understandably, one of the most requested feature. If you have any feedback, bugs to report, feature
requests, etc, please open an issue here on GitHub. I will try to address them as soon as I can. I also monitor the
tag zip4j on [Stack Overflow][10].
Zip4j is the most comprehensive Java library for zip files or streams. As of this writing, it is the only Java library
which has support for zip encryption, apart from several other features. It tries to make handling zip files/streams
a lot more easier. No more clunky boiler plate code with input streams and output streams. As you can see in the usage
section below, working with zip files can now even be a single line of code, compared to [this][5]. I mean no offense
to the Java's built-in zip support. In fact, this library depends on Java's built-in zip code and it would have been
significantly more complicated challenging if I had to write compression logic as well. But lets be honest, working with zip
files or streams can be a lot of boiler plate code. The main goal of this library is to provide a simple API for all
usual actions of a zip file or streams by doing the heavy lifting within the library and not have developers worry about
having to deal with streams, etc. Apart from usability, another important goal of this library is to provide support for
as many zip features as possible, which brings me to:
Zip4j was started by me (Srikanth Reddy Lingala) back in 2008/2009, when I realized the lack of support for majority of zip format features in Java. And also working with zip files was, as mentioned several times above, a lot of boiler plate code, having to deal with streams (worse still, it was back in the days when there was no try-with-resources in Java). There was also no comprehensive library which supports zip features. So, I decided to write one, and approximately after a year, the first version was out. The response was truly overwhelming, and I got a lot of support right from the next day of release. It was not put on GitHub as git/GitHub was not as popular as it is now. Code was hosted on my website, as, guess what, a zip file :). And unfortunately, after a year or two after the initial release, life got busy and I was not able to support Zip4j as much as I wanted to. But the overwhelming encouragement I got over the years made me start working on Zip4j once again, and makes me support Zip4j as much as I can.
JDK 7 or later*
* Zip4j is written on JDK 8, as some of the features (NIO) that Zip4j supports requires features available only in JDK 8. However, considering the fact that Zip4j is widely used in Android, and to support older versions of Android, Zip4j supports JDK 7 as well. In cases where the feature/class from JDK 8 is missing, Zip4j falls back to the features available in JDK 7. In other words, when running on JDK 7, not all features will be supported.
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.6</version>
</dependency>Please check the latest version number on [Maven Central][6].
new ZipFile("filename.zip").addFile("filename.ext");Or
new ZipFile("filename.zip").addFile(new File("filename.ext"));new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"));Since v2.6, it is possible to exclude certain files when adding a folder to zip by using an ExcludeFileFilter
ExcludeFileFilter excludeFileFilter = filesToExclude::contains;
ZipParameters zipParameters = new ZipParameters();
zipParameters.setExcludeFileFilter(excludeFileFilter);
new ZipFile("filename.zip").addFolder(new File("/users/some_user/folder_to_add"), zipParameters);new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());Passing in new ZipParameters(), as in the above example, will make Zip4j use default zip parameters. Please look at
[ZipParameters][7] to see the default configuration.
By default Zip4j uses Deflate compression algorithm to compress files. However, if you would like to not use any compression (called STORE compression), you can do so as shown in the example below:
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(CompressionMethod.STORE);
new ZipFile("filename.zip").addFile("fileToAdd", zipParameters);You can similarly pass in zip parameters to all the other examples to create a zip file of STORE compression.
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
// Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
List<File> filesToAdd = Arrays.asList(
new File("somefile"),
new File("someotherfile")
);
ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);Instead of AES, replace zipParameters.setEncryptionMethod(EncryptionMethod.AES); with
zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD);. You can omit the line to set AES key strength. As
the name suggests, this is only applicable for AES encryption.
In all the above examples, you can similarly pass in zip parameters with appropriate password configuration to create a password protected zip file.
If you want to split the zip file over several files when the size exceeds a particular limit, you can do so like this:
List<File> filesToAdd = Arrays.asList(
new File("somefile"),
new File("someotherfile")
);
ZipFile zipFile = new ZipFile("filename.zip");
zipFile.createSplitZipFile(filesToAdd, new ZipParameters(), true, 10485760); // using 10MB in this examplePassing in new ZipParameters(), as in the above example, will make Zip4j use default zip parameters. Please look at
[ZipParameters][7] to see the default configuration.
Zip file format specifies a minimum of 65536 bytes (64KB) as a minimum length for split files. Zip4j will throw an exception if anything less than this value is specified.
To create a split zip with password protection, pass in appropriate ZipParameters as shown in the example below:
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
List<File> filesToAdd = Arrays.asList(
new File("somefile"),
new File("someotherfile")
);
ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
zipFile.createSplitZipFile(filesToAdd, zipParameters, true, 10485760); // using 10MB in this exampleZip64 is a zip feature which allows support for zip files when the size of the zip file exceeds the maximum that can be stored in 4 bytes (i.e., greater than 4,294,967,295 bytes). Traditionally, zip headers have a provision of 4 bytes to store for file sizes. But with growing file sizes compared to a few decades back, zip file format extended support of file sizes which extends 4 bytes by adding additional headers which uses 8 bytes for file sizes (compressed and uncompressed file sizes). This feature is known as Zip64.
Zip4j will automatically make a zip file with Zip64 format and add appropriate headers, when it detects the zip file to be crossing this file size limit. You do not have to explicitly specify any flag for Zip4j to use this feature.
new ZipFile("filename.zip").extractAll("/destination_directory");new ZipFile("filename.zip", "password".toCharArray()).extractAll("/destination_directory");new ZipFile("filename.zip").extractFile("fileNameInZip.txt", "/destination_directory");new ZipFile("filename.zip").extractFile("folderNameInZip/", "/destination_directory");new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory");Since v2.6.0: If the file name represents a directory, Zip4j will extract all files in the zip that are part of this directory.
Below example will extract the file fileNameInZip.txt from the zip file to the output directory /destination_directory
and will give the file the name newfileName.txt. Without the third parameter of the new file name, the same name as the
file in the zip will be used, which in this case is fileNameInZip.txt. If the file being extracted is a directory,
newFileName parameter will be used as the directory name.
new ZipFile("filename.zip", "password".toCharArray()).extractFile("fileNameInZip.txt", "/destination_directory", "newfileName.txt");ZipFile zipFile = new ZipFile("filename.zip");
FileHeader fileHeader = zipFile.getFileHeader("entry_name_in_zip.txt");
InputStream inputStream = zipFile.getInputStream(fileHeader);You can now use this input stream to read content from it/write content to an output stream. Please note that the
entry/file name is relative to the directory it is in. If entry_name_in_zip.txt is in a folder called "root_folder" in
the zip, then you have to use zipFile.getFileHeader("root_folder/entry_name_in_zip.txt");.
new ZipFile("filename.zip").removeFile("fileNameInZipToRemove");If fileNameInZipToRemove represents a folder all the files and folders under this folder will be removed as well
(this is valid since v2.5.0 of Zip4j. All prior versions remove just the single entry even if it is a folder).
Please note that the file name is relative the root folder in zip. That is, if the file you want to remove exists in a folder call
No open issues yet, or sync has not completed.