Overview
Java provides built-in classes in the java.util.zip package for creating ZIP archives. The ZipOutputStream class handles the compression process, while ZipEntry represents individual files within the archive.
Implementation
Creating the ZIP Output Stream
First, establish the output stream for the archive file:
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipOutputStream;
public class ZipCompressor {
public void createArchive(String archivePath) throws IOException {
try (FileOutputStream fos = new FileOutputStream(archivePath);
ZipOutputStream zos = new ZipOutputStream(fos)) {
// Compression logic will go here
}
}
}
Using try-with-resources ensures proper resource cleanup. The ZipOutputStream wraps the file output stream to handle ZIP format encoding.
Adding Files to the Archive
To compress individual files, create ZipEntry instances and write file data through the output stream:
public void addFile(ZipOutputStream zos, File sourceFile) throws IOException {
if (sourceFile.isDirectory()) {
return;
}
try (FileInputStream fis = new FileInputStream(sourceFile)) {
ZipEntry entry = new ZipEntry(sourceFile.getName());
zos.putNextEntry(entry);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
zos.closeEntry();
}
}
The putNextEntry() method marks the start of a new archive entry, and closeEntry() signals the end of the current file's data.
Compressing Multiple Files
A complete example that compresses an entire directory:
public void compressDirectory(String sourceDir, String archivePath) throws IOException {
File directory = new File(sourceDir);
try (FileOutputStream fos = new FileOutputStream(archivePath);
ZipOutputStream zos = new ZipOutputStream(fos)) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
addFile(zos, file);
}
}
}
}
}
Complete Working Example
import java.io.*;
import java.util.zip.*;
public class ArchiveTool {
public static void main(String[] args) {
ArchiveTool tool = new ArchiveTool();
try {
tool.compressFile(new File("data.txt"), "output.zip");
System.out.println("Compression complete");
} catch (IOException e) {
e.printStackTrace();
}
}
public void compressFile(File source, String zipPath) throws IOException {
try (FileOutputStream fos = new FileOutputStream(zipPath);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(source)) {
zos.putNextEntry(new ZipEntry(source.getName()));
byte[] dataBuffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(dataBuffer)) > 0) {
zos.write(dataBuffer, 0, bytesRead);
}
zos.closeEntry();
}
}
}
Key Points
- Always close entries before starting the next file
- Use try-with-resources for automatic stream management
- Buffer sizes affect memory usage versus I/O pefrormance
- The ZipEntry name should be relative to the archive root