zip4j
| Language | Java (8+), works on Android |
|---|---|
| License | Apache 2.0 |
| Repository | github.com/srikanth-lingala/zip4j |
| Documentation | README, javadoc |
| Depends on | nothing |
| Read / write | yes / yes, ZIP64, AES-128/256 and ZipCrypto, stored and DEFLATE, split archives |
zip4j does common ZIP tasks in one line: new ZipFile("a.zip").extractAll("out"). Its main feature is encryption: it creates and reads both AES (WinZip AES) and ZipCrypto archives, which the JDK can’t do. It also adds, removes and renames entries in existing archives, creates and merges split archives, reports progress and has its own ZipInputStream / ZipOutputStream with password support.
It supports stored and DEFLATE only, not bzip2, LZMA or Zstandard.
Installation#
Maven:
XML
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.11.6</version>
</dependency>
Gradle:
implementation("net.lingala.zip4j:zip4j:2.11.6")
Basic usage: create and extract a ZIP#
Java
import java.io.File;
import java.io.IOException;
import net.lingala.zip4j.ZipFile;
public class Example {
public static void main(String[] args) throws IOException {
try (ZipFile zip = new ZipFile("out.zip")) {
zip.addFile(new File("notes.txt"));
zip.addFolder(new File("photos")); // adds photos/ recursively
}
try (ZipFile zip = new ZipFile("out.zip")) {
zip.extractAll("extracted");
}
}
}
ZipFile operations throw net.lingala.zip4j.exception.ZipException, a subclass of IOException.
How to create a password-protected ZIP with AES#
Java
import java.io.File;
import java.util.List;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
ZipParameters params = new ZipParameters();
params.setEncryptFiles(true);
params.setEncryptionMethod(EncryptionMethod.AES); // or ZIP_STANDARD (ZipCrypto, weak)
params.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
try (ZipFile zip = new ZipFile("secret.zip", "my password".toCharArray())) {
zip.addFiles(List.of(new File("a.pdf"), new File("b.pdf")), params);
}
How to extract a password-protected ZIP#
Java
try (ZipFile zip = new ZipFile("secret.zip")) {
if (zip.isEncrypted()) {
zip.setPassword("my password".toCharArray());
}
zip.extractAll("out");
}
How to list files and extract one#
Java
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
try (ZipFile zip = new ZipFile("in.zip")) {
for (FileHeader h : zip.getFileHeaders()) {
System.out.printf("%-40s %10d -> %10d%s%n", h.getFileName(),
h.getUncompressedSize(), h.getCompressedSize(), h.isEncrypted() ? " (encrypted)" : "");
}
zip.extractFile("docs/readme.txt", "out"); // keeps the docs/ folder
zip.removeFile("old.log"); // modifies the archive
}
How to set the compression level#
Java
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
ZipParameters params = new ZipParameters();
params.setCompressionMethod(CompressionMethod.DEFLATE); // or STORE
params.setCompressionLevel(CompressionLevel.MAXIMUM); // FASTEST, FAST, NORMAL, MAXIMUM
zip.addFolder(new File("docs"), params);
Tips#
zip.createSplitZipFile(files, params, true, 10485760)writes 10 MB parts;mergeSplitFilesjoins them into one archive.zip.setRunInThread(true)pluszip.getProgressMonitor()runs long operations in the background with progress.zip.setCharset(Charset.forName("Cp437"))reads names from old archives without the UTF-8 flag.- zip4j validates extraction paths and refuses entries that would be written outside the target folder.