Java Zip Utility Class - ZipUtils

In this article, we will discuss a few commonly used Java Zip utility methods and provide sample JUnit test cases for them.

The ZipUtils class contains the following generic methods:

  1. zipFiles(List<File> files, OutputStream outputStream) - Zips a collection of files to a destination zip output stream.
  2. unZipFiles(File zipFile, File outputFolder) - Unzips a zip file into an output folder.
  3. zipFiles(List<File> files, File zipFile) - Zips a collection of files to a destination zip file.
  4. unZipFiles(InputStream inputStream, File outputFolder) - Unzips a zip from an input stream into an output folder.

Java Zip Utility Class - ZipUtils

Note that ZipUtils.java contains a third-party library - apache-commons-io.

ZipUtils.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * Utility for zipping files.
 * @author javaguides
 */
public class ZipUtils {

    /**
     * Zips a collection of files to a destination zip output stream.
     *
     * @param files        A collection of files and directories
     * @param outputStream The output stream of the destination zip file
     * @throws IOException if an I/O error occurs
     */
    public static void zipFiles(List<File> files, OutputStream outputStream) throws IOException {
        ZipOutputStream zos = new ZipOutputStream(outputStream);

        for (File file : files) {
            if (file.isDirectory()) {   // if it's a folder
                addFolderToZip("", file, zos);
            } else {
                addFileToZip("", file, zos);
            }
        }

        zos.finish();
    }

    /**
     * Adds a directory to the current zip
     *
     * @param path   the path of the parent folder in the zip
     * @param folder the directory to be added
     * @param zos    the current zip output stream
     * @throws IOException if an I/O error occurs
     */
    private static void addFolderToZip(String path, File folder, ZipOutputStream zos) throws IOException {
        String currentPath = StringUtils.isNotEmpty(path) ? path + "/" + folder.getName() : folder.getName();

        for (File file : folder.listFiles()) {
            if (file.isDirectory()) {
                addFolderToZip(currentPath, file, zos);
            } else {
                addFileToZip(currentPath, file, zos);
            }
        }
    }

    /**
     * Adds a file to the current zip output stream
     *
     * @param path the path of the parent folder in the zip
     * @param file the file to be added
     * @param zos  the current zip output stream
     * @throws IOException if an I/O error occurs
     */
    private static void addFileToZip(String path, File file, ZipOutputStream zos) throws IOException {
        String currentPath = StringUtils.isNotEmpty(path) ? path + "/" + file.getName() : file.getName();

        zos.putNextEntry(new ZipEntry(currentPath));

        InputStream is = new BufferedInputStream(new FileInputStream(file));
        try {
            IOUtils.copy(is, zos);
        } finally {
            IOUtils.closeQuietly(is);
        }
        zos.closeEntry();
    }

    /**
     * Zips a collection of files to a destination zip file.
     *
     * @param files   A collection of files and directories
     * @param zipFile The path of the destination zip file
     * @throws IOException if an I/O error occurs
     */
    public static void zipFiles(List<File> files, File zipFile) throws IOException {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(zipFile));
        try {
            zipFiles(files, os);
        } finally {
            IOUtils.closeQuietly(os);
        }
    }

    /**
     * Unzips a zip from an input stream into an output folder.
     *
     * @param inputStream  the zip input stream
     * @param outputFolder the output folder where the files will be extracted
     * @throws IOException if an I/O error occurs
     */
    public static void unZipFiles(InputStream inputStream, File outputFolder) throws IOException {
        ZipInputStream zis = new ZipInputStream(inputStream);
        ZipEntry ze = zis.getNextEntry();

        while (ze != null) {
            File file = new File(outputFolder, ze.getName());
            OutputStream os = new BufferedOutputStream(FileUtils.openOutputStream(file));

            try {
                IOUtils.copy(zis, os);
            } finally {
                IOUtils.closeQuietly(os);
            }

            zis.closeEntry();
            ze = zis.getNextEntry();
        }
    }

    /**
     * Unzips a zip file into an output folder.
     *
     * @param zipFile      the zip file
     * @param outputFolder the output folder where the files will be extracted
     * @throws IOException if an I/O error occurs
     */
    public static void unZipFiles(File zipFile, File outputFolder) throws IOException {
        InputStream is = new BufferedInputStream(new FileInputStream(zipFile));
        try {
            unZipFiles(is, outputFolder);
        } finally {
            IOUtils.closeQuietly(is);
        }
    }
}

JUnit Test Cases for ZipUtils

Here are some JUnit test cases to test the methods of ZipUtils.

ZipUtilsTest.java

package com.javaguides.javaio.utility;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class ZipUtilsTest {

    @Test
    public void zipFilesTest() throws IOException {
        FileOutputStream fos = new FileOutputStream("C:/Project_Work/samples/src_sample1.zip");
        File file = new File("C:/Project_Work/samples/outputzip/sample.txt");
        File file1 = new File("C:/Project_Work/samples/outputzip/sample1.txt");
        File file2 = new File("C:/Project_Work/samples/outputzip/sample2.txt");

        List<File> files = new ArrayList<>();
        files.add(file);
        files.add(file1);
        files.add(file2);
        ZipUtils.zipFiles(files, fos);
    }

    @Test
    public void unZipFilesTest() throws IOException {
        File zipFile = new File("C:/Project_Work/samples/src_sample1.zip");
        File unZipOutputFolder = new File("C:/Project_Work/samples/dest_folder");
        ZipUtils.unZipFiles(zipFile, unZipOutputFolder);
    }
}

Related Utility Classes

By using the ZipUtils class, you can easily zip and unzip files in Java. The provided examples and JUnit test cases will help you understand how to use these utility methods effectively. Feel free to modify and extend the utility class to fit your specific needs. Happy coding!

Comments