Java zip file with directory

Zip and Unzip Files in Java

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(ListPath> 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 :-

ListPath> 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.

See Also

Ashish Lahoti avatar

Ashish Lahoti is a Software Engineer with 12+ years of experience in designing and developing distributed and scalable enterprise applications using modern practices. He is a technology enthusiast and has a passion for coding & blogging.

Источник

How to zip directories programmatically using Java

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)
      • w rite 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()

      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(ListlistFiles, 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 < ListlistFiles = new ArrayList(); 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 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 = ; String zipFile = "E:/Test/MyPics.zip"; ZipUtility zipUtil = new ZipUtility(); try < zipUtil.zip(myFiles, zipFile); >catch (Exception ex) < // some errors occurred ex.printStackTrace(); >> >

        Other Java File IO Tutorials:

        About the Author:

        Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.

        Источник

        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() < @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

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

        Источник

        Читайте также:  Unique page title - My Site
Оцените статью