This article is about how to write a utility class for adding files and directories into a compressed zip archive, using built-in Java API.

The java.util.zip package provides the following classes for adding files and directories into a ZIP archive:

    • ZipOutputStream: this is the main class which can be used for making zip file and adding files and directories (entries) to be compressed in a single archive. Here are some important usages of this class:

      • create a zip via its constructor ZipOutputStream(FileOutputStream)
      • add entries of files and directories via method putNextEntry(ZipEntry)
      • write binary data to current entry via method write(byte[] bytes, int offset, int length)
      • close current entry via method closeEntry()
      • save and close the zip file via method close()
    •           ZipEntry: this class represents an entry to be added to the zip file. Its constructor takes a String which represents path of the file/directory being added. The path must be in the following form:

folder_1/subfolder_1/subfolder_2/…/subfolder_n/file.ext

In addition, the BufferedInputStream class is used to read content of input file via its method read(byte[]). While reading file’s content, write the bytes read into the current zip entry via ZipOutputStream’s write() method.

 

 

Following is source code of ZipUtility.java class:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * This utility compresses a list of files to standard ZIP format file.
 * It is able to compress all sub files and sub directories, recursively.
 * @author www.codejava.net
 *
 */
public class ZipUtility {
    /**
     * A constants for buffer size used to read/write data
     */
    private static final int BUFFER_SIZE = 4096;
    /**
     * Compresses a list of files to a destination zip file
     * @param listFiles A collection of files and directories
     * @param destZipFile The path of the destination zip file
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void zip(List<File> listFiles, String destZipFile) throws FileNotFoundException,
            IOException {
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destZipFile));
        for (File file : listFiles) {
            if (file.isDirectory()) {
                zipDirectory(file, file.getName(), zos);
            } else {
                zipFile(file, zos);
            }
        }
        zos.flush();
        zos.close();
    }
    /**
     * Compresses files represented in an array of paths
     * @param files a String array containing file paths
     * @param destZipFile The path of the destination zip file
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void zip(String[] files, String destZipFile) throws FileNotFoundException, IOException {
        List<File> listFiles = new ArrayList<File>();
        for (int i = 0; i < files.length; i++) {
            listFiles.add(new File(files[i]));
        }
        zip(listFiles, destZipFile);
    }
    /**
     * Adds a directory to the current zip output stream
     * @param folder the directory to be  added
     * @param parentFolder the path of parent directory
     * @param zos the current zip output stream
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void zipDirectory(File folder, String parentFolder,
            ZipOutputStream zos) throws FileNotFoundException, IOException {
        for (File file : folder.listFiles()) {
            if (file.isDirectory()) {
                zipDirectory(file, parentFolder + "/" + file.getName(), zos);
                continue;
            }
            zos.putNextEntry(new ZipEntry(parentFolder + "/" + file.getName()));
            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream(file));
            long bytesRead = 0;
            byte[] bytesIn = new byte[BUFFER_SIZE];
            int read = 0;
            while ((read = bis.read(bytesIn)) != -1) {
                zos.write(bytesIn, 0, read);
                bytesRead += read;
            }
            zos.closeEntry();
        }
    }
    /**
     * Adds a file to the current zip output stream
     * @param file the file to be added
     * @param zos the current zip output stream
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void zipFile(File file, ZipOutputStream zos)
            throws FileNotFoundException, IOException {
        zos.putNextEntry(new ZipEntry(file.getName()));
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
                file));
        long bytesRead = 0;
        byte[] bytesIn = new byte[BUFFER_SIZE];
        int read = 0;
        while ((read = bis.read(bytesIn)) != -1) {
            zos.write(bytesIn, 0, read);
            bytesRead += read;
        }
        zos.closeEntry();
    }
}

 

The ZipUtility class has two public methods for adding files and directories to a zip archive:

    •           zip(List<File> listFiles, String destZipFile): accepts a list of File objects to be added to the destZipFile.
    •           zip(String[] files, String destZipFile): accepts an array of file paths to be added to the destZipFile.

 

And source code of a test class, ZipUtilityTest.java:

/**
 * A console application that tests the ZipUtility class
 * @author www.codejava.net
 *
 */
public class ZipUtilityTest {
    public static void main(String[] args) {
        String[] myFiles = {"E:/Test/PIC1.JPG",
                            "E:/Test/PIC2.JPG",
                            "E:/Test/PIC3.JPG",
                            "E:/Test/PIC4.JPG"};
        String zipFile = "E:/Test/MyPics.zip";
        ZipUtility zipUtil = new ZipUtility();
        try {
            zipUtil.zip(myFiles, zipFile);
        } catch (Exception ex) {
            // some errors occurred
            ex.printStackTrace();
        }
    }
}

 

Recommended Book: Java I/O

Attachments:
Download this file (ZipUtility.java)ZipUtility.java[utility class]3 kB
Download this file (ZipUtilityTest.java)ZipUtilityTest.java[test class]0.5 kB
Start learning on Udemy today!