Zipping and Unzipping in Java

Zipping and Unzipping in Java

In this post, we will learn Zipping and Unzipping in Java using java.util.zip API. We will also discuss some third-party API to perform these tasks. 

1.  Zip a File

We will be performing a simple operation to zip a single file into an archive.

public class ZipSingleFile {

    public static void main(String[] args) throws IOException {

        String sourceFile = "/Users/umesh/personal/tutorials/source/index.html";
        String zipName="/Users/umesh/personal/tutorials/source/testzip.zip";

        File targetFile = new File(sourceFile);

        ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipName));
        zipOutputStream.putNextEntry(new ZipEntry(targetFile.getName()));
        FileInputStream inputStream = new FileInputStream(targetFile);

        final byte[] buffer = new byte[1024];
        int length;
        while((length = inputStream.read(buffer)) >= 0) {
            zipOutputStream.write(buffer, 0, length);
        }
        zipOutputStream.close();
        inputStream.close();
    }

}

2.  Zip Multiple Files / Directories Java8

Creating zip for a single file is not very interesting or real life solution, we will be improving our program with an option to zip entire directory using Files.walk method.

public class ZipDirectory {

    public static void main(String[] args) throws IOException {

        String sourceDirectoryPath = "/Users/umesh/personal/tutorials/source";
        String zipFilePath = "/Users/umesh/personal/tutorials/source.zip";

        zipDirectory(sourceDirectoryPath, zipFilePath);
    }

    public static void zipDirectory(String sourceDirectoryPath, String zipPath) throws IOException {
        Path zipFilePath = Files.createFile(Paths.get(zipPath));

        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
            Path sourceDirPath = Paths.get(sourceDirectoryPath);

            Files.walk(sourceDirPath).filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        ZipEntry zipEntry = new ZipEntry(sourceDirPath.relativize(path).toString());
                        try {
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(Files.readAllBytes(path));
                            zipOutputStream.closeEntry();
                        } catch (Exception e) {
                            System.err.println(e);
                        }
                    });
        }
    }
}

 

2.  Zip Multiple Files / Directories Java7

public class ZipDirectoryFilesWalk {

    public static void main(String[] args) throws IOException {

        Path sourceDirectoryPath = Paths.get("/Users/umesh/personal/tutorials/source");
        Path zipFilePath = Paths.get("/Users/umesh/personal/tutorials/source.zip");

        zipDirectory(sourceDirectoryPath, zipFilePath);
    }

    public static void zipDirectory(Path sourceDirectory, Path zipFilePath) throws IOException {

        try (FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath.toFile());
             ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)
        ) {
            Files.walkFileTree(sourceDirectory, new SimpleFileVisitor<Path>() {

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                        throws IOException {
                    zipOutputStream.putNextEntry(new ZipEntry(sourceDirectory.relativize(file).toString()));
                    Files.copy(file, zipOutputStream);
                    zipOutputStream.closeEntry();
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                        throws IOException {
                    zipOutputStream.putNextEntry(new ZipEntry(sourceDirectory.relativize(dir).toString() + "/"));
                    zipOutputStream.closeEntry();
                    return FileVisitResult.CONTINUE;
                }

            });
        }
    }
}

In the above examples, we saw different options to Zipping Files and Directories in Java using Java7 and Java8.

3. Unzip  Directory

public class UnZipDirectory {

    public static void main(String[] args) throws IOException {

        String unzipLocation = "/Users/umesh/personal/tutorials/unzip";
        String zipFilePath = "/Users/umesh/personal/tutorials/source.zip";
        unzip(zipFilePath, unzipLocation);
    }

    public static void unzip(final String zipFilePath, final String unzipLocation) throws IOException {

        if (!(Files.exists(Paths.get(unzipLocation)))) {
            Files.createDirectories(Paths.get(unzipLocation));
        }
        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry entry = zipInputStream.getNextEntry();
            while (entry != null) {
                Path filePath = Paths.get(unzipLocation, entry.getName());
                if (!entry.isDirectory()) {
                    unzipFiles(zipInputStream, filePath);
                } else {
                    Files.createDirectories(filePath);
                }

                zipInputStream.closeEntry();
                entry = zipInputStream.getNextEntry();
            }
        }
    }

    public static void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException {

        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) {
            byte[] bytesIn = new byte[1024];
            int read = 0;
            while ((read = zipInputStream.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        }

    }
}

In this post, we learned how to zip and unzip files or directory using core Java features. Read our articles List all files from a directory in Java to learn how to recursively transverse folders to zip multiple files.

If you want more sophisticated API to perform other operation on the zip files, you can check following open source libraries

  1. zt-zip
  2. zip4j

All the code of this article is available Over on Github. This is a Maven-based project.

5 thoughts on “Zipping and Unzipping in Java”

  1. Zipped it using Java8 sample.. but getting error while manullay unzipping the file..

    Archive: attach2.zip
    End-of-central-directory signature not found. Either this file is not
    a zipfile, or it constitutes one disk of a multi-part archive. In the
    latter case the central directory and zipfile comment will be found on
    the last disk(s) of this archive.
    unzip: cannot find zipfile directory in one of attach2.zip or
    attach2.zip.zip, and cannot find attach2.zip.ZIP, period.

Comments are closed.