How do I compress or zip a directory recursively?

In this example you are going to learn how to zip or compress a directory recursively. The zip file format allows us to compress multiple files. We use the java.util.zip.ZipOutputStream to compress the file. Each entry in the zip file is represented by the java.util.zip.ZipEntry class.

To compress a directory we must first get all the list of files in the specified directory and including all files in the sub directory. In the example this task is handled by the getFileList() method. This method store the file list in the fileList variable to be use later during the compression process to create the ZipEntry.

Below is the code example showing you how to compress multiple files using zip.

package org.kodejava.example.zip;

import java.io.File;
import java.io.FileInputStream;
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;

public class ZipDirectoryExample {
    private List<String> fileList = new ArrayList<>();

    public static void main(String[] args) {
        String dir = "D:\\Data";
        String zipFile = "D:\\Data.zip";

        ZipDirectoryExample zip = new ZipDirectoryExample();
        zip.compressDirectory(dir, zipFile);
    }

    private void compressDirectory(String dir, String zipFile) {
        File directory = new File(dir);
        getFileList(directory);

        try {
            FileOutputStream fos  = new FileOutputStream(zipFile);
            ZipOutputStream zos = new ZipOutputStream(fos);

            for (String filePath : fileList) {
                System.out.println("Compressing: " + filePath);

                //
                // Creates a zip entry.
                //
                String name = filePath.substring(directory.getAbsolutePath().length() + 1,
                        filePath.length());
                ZipEntry zipEntry = new ZipEntry(name);
                zos.putNextEntry(zipEntry);

                //
                // Read file content and write to zip output stream.
                //
                FileInputStream fis = new FileInputStream(filePath);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }

                //
                // Close the zip entry and the file input stream.
                //
                zos.closeEntry();
                fis.close();
            }

            //
            // Close zip output stream and file output stream. This will
            // complete the compression process.
            //
            zos.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Get files list from the directory recursive to the sub directory.
     */
    private void getFileList(File directory) {
        File[] files = directory.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                if (file.isFile()) {
                    fileList.add(file.getAbsolutePath());
                } else {
                    getFileList(file);
                }
            }
        }

    }
}

The code snippet above will compress the D:\Data directory and it will produce a zip file called Data.zip. When running the program you can see something like this in the console:

Compressing: D:\DataAa.txt
Compressing: D:\DataAA1a1.txt
Compressing: D:\DataBb.txt
Compressing: D:\DataCc.txt
Compressing: D:\DataCC1c1.txt
Compressing: D:\DataDd.txt

How do I read a zip file checksum value?

package org.kodejava.example.util;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.CheckedInputStream;
import java.util.zip.Adler32;

public class UnzipWithChecksum {
    public static void main(String[] args) {
        String zipname = "data-1.zip";

        try {
            FileInputStream fis = new FileInputStream(zipname);

            //
            // Creating input stream that also maintains the checksum of the
            // data which later can be used to validate data integrity.
            //
            CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));
            ZipEntry entry;

            //
            // Read each entry from the ZipInputStream until no more entry found
            // indicated by a null return value of the getNextEntry() method.
            //
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Unzipping: " + entry.getName());

                int size;
                byte[] buffer = new byte[2048];

                FileOutputStream fos = new FileOutputStream(entry.getName());
                BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }
                bos.flush();
                bos.close();
            }

            zis.close();
            fis.close();

            //
            // Print out the checksum value
            //
            System.out.println("Checksum = " + checksum.getChecksum().getValue());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

How do I decompress a zip file using ZipFile?

In this example we use the java.util.zip.ZipFile class to decompress and extract a zip file.

package org.kodejava.example.util.zip;

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
import java.io.*;

public class ZipFileUnzipDemo {
    public static void main(String[] args) {
        String zipname = "data.zip";

        try {
            ZipFile zipFile = new ZipFile(zipname);
            Enumeration enumeration = zipFile.entries();

            while (enumeration.hasMoreElements()) {
                ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
                System.out.println("Unzipping: " + zipEntry.getName());

                BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(zipEntry));

                int size;
                byte[] buffer = new byte[2048];

                FileOutputStream fos = new FileOutputStream(zipEntry.getName());
                BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                while ((size = bis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }

                bos.flush();
                bos.close();
                fos.close();

                bis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

How do I decompress a zip file using ZipInputStream?

The code below shows how to decompress and extract files from a zip archive. In the example we use the java.util.zip.ZipInputStream class.

package org.kodejava.example.util.zip;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;

public class UnzipDemo {
    public static void main(String[] args) {
        String zipName = "data.zip";

        try {
            FileInputStream fis = new FileInputStream(zipName);
            ZipInputStream zis = new ZipInputStream(
                    new BufferedInputStream(fis));
            ZipEntry entry;

            //
            // Read each entry from the ZipInputStream until no
            // more entry found indicated by a null return value
            // of the getNextEntry() method.
            //
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Unzipping: " + entry.getName());

                int size;
                byte[] buffer = new byte[2048];

                FileOutputStream fos =
                        new FileOutputStream(entry.getName());
                BufferedOutputStream bos =
                        new BufferedOutputStream(fos, buffer.length);

                while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }
                bos.flush();
                bos.close();
            }

            zis.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

How do I read entries in a zip / compressed file?

package org.kodejava.example.util.zip;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipFileSample {
    public static void main(String[] args) {
        try {
            // Create an instance of ZipFile to read a zip file
            // called sample.zip
            ZipFile zip = new ZipFile(new File("data.zip"));

            // Here we start to iterate each entries inside
            // sample.zip
            for (Enumeration e = zip.entries(); e.hasMoreElements(); ) {
                // Get ZipEntry which is a file or a directory
                ZipEntry entry = (ZipEntry) e.nextElement();

                // Get some information about the entry such as
                // file name, its size.
                System.out.println("File name: " + entry.getName()
                        + "; size: " + entry.getSize()
                        + "; compressed size: "
                        + entry.getCompressedSize());
                System.out.println();

                // Now we want to get the content of this entry.
                // Get the InputStream, we read through the input
                // stream until all the content is read.
                InputStream is = zip.getInputStream(entry);
                InputStreamReader isr = new InputStreamReader(is);

                char[] buffer = new char[1024];
                while (isr.read(buffer, 0, buffer.length) != -1) {
                    String s = new String(buffer);
                    // Here we just print out what is inside the
                    // buffer.
                    System.out.println(s.trim());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}