In Java, handling ZIP files is primarily done using the java.util.zip package. The key classes you’ll use are ZipOutputStream for creating (zipping) files and ZipInputStream (or ZipFile) for extracting (unzipping) them.
Here is a breakdown of how to perform both operations.
1. Zipping Files
To zip files, you wrap a FileOutputStream with a ZipOutputStream. For every file you want to add, you create a ZipEntry and write the file’s data to the stream.
package org.kodejava.io;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipExample {
public static void main(String[] args) {
String sourceFile = "example.txt";
String zipFile = "compressed.zip";
try (FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(sourceFile)) {
// Create a new ZipEntry for the file
ZipEntry zipEntry = new ZipEntry(sourceFile);
zos.putNextEntry(zipEntry);
// Read source file and write to the ZipOutputStream
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) >= 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
System.out.println("File zipped successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. Unzipping Files
To extract files, you use ZipInputStream to iterate through each ZipEntry. For each entry, you create a FileOutputStream to write the data back to the disk.
package org.kodejava.io;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnzipExample {
public static void main(String[] args) {
String zipFile = "compressed.zip";
String destDir = "output_folder";
File dir = new File(destDir);
if (!dir.exists()) dir.mkdirs();
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
File filePath = new File(destDir, entry.getName());
// Ensure parent directories exist (crucial for nested zips)
if (entry.isDirectory()) {
filePath.mkdirs();
} else {
new File(filePath.getParent()).mkdirs();
try (FileOutputStream fos = new FileOutputStream(filePath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
zis.closeEntry();
entry = zis.getNextEntry();
}
System.out.println("Unzipped successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pro-Tips:
- Try-with-resources: Always use try-with-resources (as shown above) to ensure that streams are closed automatically, preventing memory leaks and file locks.
- Buffering: For large files, wrapping your streams in
BufferedInputStreamandBufferedOutputStreamcan significantly improve performance. - ZipFile vs ZipInputStream: If you need random access to specific files within a ZIP without reading the whole thing, use the
ZipFileclass instead ofZipInputStream. - ZipSlip Vulnerability: When unzipping, always validate that the entry’s name doesn’t contain
..(parent directory references) to prevent files from being written outside the target directory.
