- Zipping and Unzipping in Java
- 1. Zip a File
- 2. Zip Multiple Files / Directories Java8
- 2. Zip Multiple Files / Directories Java7
- 3. Unzip Directory
- Zip and Unzip Files in Java
- Zip a File
- Zip Multiple files
- Zip All Files and Folders in a Directory
- Unzip an Archive file
- See Also
- Java Zip and Unzip Files and Folders
- How to Zip Files in Java?
- Zip and unzip in java
- ZipOutputStream. Запись архивов
- Чтение архивов. ZipInputStream
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.
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:-
- 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.
- Initializing the ZipOutputStream in the try block so that closing the streams will be taken care by JVM.
- 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:-
- 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.
- Initializing the ZipOutputStream in the try block so that closing the streams will be taken care by JVM.
- Using Java NIO Files.walk() to iterate through all files and folders recursively in a directory using Java Streams.
- 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:-
- 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.
- Initializing the ZipInputStream in the try block so that closing the streams will be taken care by JVM.
- 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 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.
Java Zip and Unzip Files and Folders
Here we will learn about how to zip and unzip files and folders in java.
If information contains redundant data it will be tough to store and transfer the data. So we will go for compression which will give efficient representation of the data. For zipping many algorithms are there.
Java provides the java.util.zip package for zipping and unzipping the files. The class ZipOutputStream will be useful for compressing. It is an output stream filter which will write files to any File output stream in zip format. The class ZipInputStream will be useful for decompressing. It is an input stream which will read files that are in zip format.
How to Zip Files in Java?
For zipping purpose we have many algorithms. If we are not mentioning any alogorithm through any method it will use default compression method that is DEFLATED compression. Deflated compression is almost near to Huffman coding.
Now we will see one example.
Problem: We want to zip the directory which has multiple files along with sub folders.
Solution: Zipping a file is very easy. But when we are zipping a folder which contains sub folders we should take care about the relative paths of files which have to be zipped.
For example take directory named as first which is located in E disk. It contains one subfolder along with multiple files. We have to zip it now.
Step 1: We should list out all files in the directory. listFiles() method will return total files (directories + files) in that directory. We can use this method to list out the total files. For this we have to check whether it is a directory or not. If it is a directory then again list out the files in that subdirectory. Continue this process until all files are listed out. This is recursive process.
Step 2: After listing out the files, we should create a file output stream for output zip folder. So that it will create output zip folder and write the contents to it.
Step 3: We should create a zip output stream which will write file contents to the file output stream in the format of zip.
- Create an input stream for a file. So that it can read file contents.
- Create a zip Entry object for file with relative path only because if use absolute path it can’t find files so zipping is not possible. So that we can add this file to zip out stream. For adding putNextEntry() method of ZipOutputStream will be useful.
- Now zip output stream will write these file contents in the format of zip to the file output stream.
- Close zip entry and close file input stream
This is the process of zipping one file. So do the same for every file in the list.
Step 5: As zipping of all files is done. Now close all IO streams. Proper closing of IO streams will prevent the corruption of zip files.
Zip and unzip in java
Кроме общего функционала для работы с файлами Java предоставляет функциональность для работы с таким видом файлов как zip-архивы. Для этого в пакете java.util.zip определены два класса — ZipInputStream и ZipOutputStream
ZipOutputStream. Запись архивов
Для создания архива используется класс ZipOutputStream. Для создания объекта ZipOutputStream в его конструктор передается поток вывода:
ZipOutputStream(OutputStream out)
Для записи файлов в архив для каждого файла создается объект ZipEntry , в конструктор которого передается имя архивируемого файла. А чтобы добавить каждый объект ZipEntry в архив, применяется метод putNextEntry() .
import java.io.*; import java.util.zip.*; public class Program < public static void main(String[] args) < String filename = "notes.txt"; try(ZipOutputStream zout = new ZipOutputStream(new FileOutputStream("output.zip")); FileInputStream fis= new FileInputStream(filename);) < ZipEntry entry1=new ZipEntry("notes.txt"); zout.putNextEntry(entry1); // считываем содержимое файла в массив byte byte[] buffer = new byte[fis.available()]; fis.read(buffer); // добавляем содержимое к архиву zout.write(buffer); // закрываем текущую запись для новой записи zout.closeEntry(); >catch(Exception ex) < System.out.println(ex.getMessage()); >> >
После добавления объекта ZipEntry в поток нам также надо добавить в него и содержимое файла. Для этого используется метод write, записывающий в поток массив байтов: zout.write(buffer); . В конце надо закрыть ZipEntry с помощью метода closeEntry() . После этого можно добавлять в архив новые файлы — в этом случае все вышеописанные действия для каждого нового файла повторяются.
Чтение архивов. ZipInputStream
Для чтения архивов применяется класс ZipInputStream . В конструкторе он принимает поток, указывающий на zip-архив:
ZipInputStream(InputStream in)
Для считывания файлов из архива ZipInputStream использует метод getNextEntry() , который возвращает объект ZipEntry . Объект ZipEntry представляет отдельную запись в zip-архиве. Например, считаем какой-нибудь архив:
import java.io.*; import java.util.zip.*; public class Program < public static void main(String[] args) < try(ZipInputStream zin = new ZipInputStream(new FileInputStream("output.zip"))) < ZipEntry entry; String name; while((entry=zin.getNextEntry())!=null)< name = entry.getName(); // получим название файла System.out.printf("File name: %s \n", name); // распаковка FileOutputStream fout = new FileOutputStream("new" + name); for (int c = zin.read(); c != -1; c = zin.read()) < fout.write(c); >fout.flush(); zin.closeEntry(); fout.close(); > > catch(Exception ex) < System.out.println(ex.getMessage()); >> >
ZipInputStream в конструкторе получает ссылку на поток ввода. И затем в цикле выводятся все файлы и их размер в байтах, которые находятся в данном архиве.
Затем данные извлекаются из архива и сохраняются в новые файлы, которые находятся в той же папке и которые начинаются с «new».