Compressing Files into ZIP Archives in Java

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

Tags: java zip compression IO File-Handling

Posted on Fri, 08 May 2026 14:50:53 +0000 by madkris