Zip and Unzip Files in Java Zip and Unzip Files in Java

Page content

In this tutorial, we’ll learn how to zip a file or directory into an archive and how to unzip the archive into a directory using Java core libraries.

Zip a File

Let’s look at the example where we want to zip a single file into an archive:-

public static void zipFile(Path fileToZip, Path zipFile) throws IOException {
    Files.createDirectories(zipFile.getParent());
    try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile))) {
        ZipEntry zipEntry = new ZipEntry(fileToZip.toFile().getName());
        zipOutputStream.putNextEntry(zipEntry);
        if (Files.isRegularFile(fileToZip)) {
            Files.copy(fileToZip, zipOutputStream);
        }
    }
}

The below method call will zip a file /cnc/toZip/picture1.png into an archive /cnc/zip/singleFileArchive.zip:-

zipFile(Path.of("/cnc/toZip/picture1.png"), Path.of("/cnc/zip/singleFileArchive.zip"));

Make note of following in this method:-

  1. Using Java nio method Files.createDirectories() to create all directories of zip file if doesn’t exist. Unlike the Files.createDirectory() method, an exception is not thrown if it already exists.
  2. Initializing the ZipOutputStream in the try block so that closing the streams will be taken care by JVM.
  3. Using Java nio method Files.copy() to copy the file to ZipOutputStream, makes your code concise.

Zip Multiple files

Let’s look at the example where we want to zip multiple files into an archive:-

public static void zipMultipleFiles(List<Path> filesToZip, Path zipFile) throws IOException {
    Files.createDirectories(zipFile.getParent());
    try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile))) {
        for(Path fileToZip: filesToZip){
            ZipEntry zipEntry = new ZipEntry(fileToZip.toFile().getName());
            zipOutputStream.putNextEntry(zipEntry);
            if (Files.isRegularFile(fileToZip)) {
                Files.copy(fileToZip, zipOutputStream);
            }
        }
    }
}

The below method call will zip these two files picture1.png & picture2.png into an archive /cnc/zip/multiFileArchive.zip:-

List<Path> filesToZip = Arrays.asList(Path.of("/cnc/toZip/picture1.png"), Path.of("/cnc/toZip/picture2.png"));

zipMultipleFiles(filesToZip, Path.of("/cnc/zip/multiFileArchive.zip"));

Make note that we put each file entry in ZipEntry which represents the archive file.

Zip All Files and Folders in a Directory

Let’s look at the example where we want to zip all the files and folders inside a directory into an archive:-

public static void zipDirectory(Path directoryToZip, Path zipFile) throws IOException {
  Files.deleteIfExists(zipFile);
  Files.createDirectories(zipFile.getParent());
  try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFile))) {
      if (Files.isDirectory(directoryToZip)) {
          Files.walk(directoryToZip).filter(path -> !Files.isDirectory(path)).forEach(path -> {
              ZipEntry zipEntry = new ZipEntry(directoryToZip.relativize(path).toString());
              try {
                  zipOutputStream.putNextEntry(zipEntry);
                  if (Files.isRegularFile(path)) {
                      Files.copy(path, zipOutputStream);
                  }
                  zipOutputStream.closeEntry();
              } catch (IOException e) {
                  System.err.println(e);
              }
          });
      }
  }
}

The below method call will zip all the files and folders inside /cnc/toZip recursively into an archive /cnc/zip/fullDirectoryArchive.zip:-

zipDirectory(Path.of("/cnc/toZip"), Path.of("/cnc/zip/fullDirectoryArchive.zip"));

Make note of following in this method:-

  1. Using Java NIO file utility methods Files.deleteIfExists() and Files.createDirectories(), which are safe to use and doesn’t throw an exception if file or directory doesn’t exist.
  2. Initializing the ZipOutputStream in the try block so that closing the streams will be taken care by JVM.
  3. Using Java NIO Files.walk() to iterate through all files and folders recursively in a directory using Java Streams.
  4. Put each file or directory entry in the ZipEntry, which represents the archive file.

Unzip an Archive file

Let’s look at the example where we want to unzip an archive file into target directory:-

public static void unzipDirectory(Path zipFile, Path targetDirectory) throws IOException {
    if (!Files.exists(zipFile)) {
        return;
    }
    deleteDirectoryRecursively(targetDirectory);
    Files.createDirectory(targetDirectory);
    try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {
        ZipEntry entry;
        while ((entry = zipInputStream.getNextEntry()) != null) {
            final Path toPath = targetDirectory.resolve(entry.getName());
            if (entry.isDirectory()) {
                Files.createDirectory(toPath);
            } else {
                if (!Files.exists(toPath.getParent())) {
                    Files.createDirectories(toPath.getParent());
                }
                Files.copy(zipInputStream, toPath);
            }
        }
    }
}

private static void deleteDirectoryRecursively(Path dir) throws IOException {
    if (Files.exists(dir)) {
        Files.walk(dir).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
    }
}

The below method call will unzip all the files and folders inside fullDirectoryArchive.zip recursively into the directory /cnc/toUnzip:-

unzipDirectory(Path.of("/cnc/zip/fullDirectoryArchive.zip"), Path.of("/cnc/toUnzip"));

Make note of following in this method:-

  1. Doing initial validations for e.g. return and do nothing if zip file does’nt exist, delete the target directory recursively if it already exist.
  2. Initializing the ZipInputStream in the try block so that closing the streams will be taken care by JVM.
  3. Iterate through ZipEntry, which is an archive file representation and have all archive information:-
    - If it is a directory then create that directory
    - If it is a file then create all its parent directories and then copy that file

Thats it for this tutorial. Thanks for reading and happy learning!

Download the ZipFileUtil.java which have all these methods and start using in your code.