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();
        }
    }
}

 

Related Java Zip File Tutorials:

 

Other Java File IO Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (ZipUtility.java)ZipUtility.java[utility class]3 kB
Download this file (ZipUtilityTest.java)ZipUtilityTest.java[test class]0.5 kB

Add comment

   


Comments 

#6Induja2021-06-12 02:24
When I'm trying ZipDirectory method, creating an invalid zipfile
Quote
#5Induja2021-06-12 02:06
Can you please show how to use ZipDirectory method in ZipUtilityTest.java?
Quote
#4Gabrielle Guillaume2021-03-26 09:44
Hello !

Your code was really useful for me.
Just one question, I have some norwegian character in my file name. Any advise on how to set an encoding with FileInputStream ? Thanks
Quote
#3Ali2021-02-10 20:54
Thanks man, nice work
Quote
#2Antony Paul Raj2020-11-04 00:13
Great idea with simple explanation. Very nice.
Quote