Unzip zip file 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() < @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.

Читайте также:  Php echo value to html

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.

Источник

Unzipping File in Java

Unzipping zip file in Java 8 using builtin Java classes: ZipInputStream and ZipEntry. Implementation supports sub-directories as well.

Overview

Today, I will share with you how to unzip (extract) a ZIP file into a complete directory. Recently, I need a code snippet for extracting a ZIP file for QA purposes. However, the top results shown on the search engine did not work. So I decided to share my implementation with you. After reading this article, you will understand:

  • How to unzip a given ZIP file?
  • Required and optional parameters before launching the unzip command
  • Limitations

TL;DR

If you don’t have time to read the entire article, here is the summary. You can copy-paste the following code snippet. Then, you have to complete 2 parameters: the source file path (ZIP) to extract ( sourceZip ) and the target directory to store the extracted files ( targetDir ). Note that a new directory without the “.zip” suffix will be created in that target directory. For example, extracting zip file tomcat.zip to ~/Downloads target directory, the extracted files will be stored at ~/Downloads/tomcat .

/** * Execute the unzip command. * * @throws IOException if any I/O error occurs */ public void exec() throws IOException  Path root = targetDir.normalize(); try (InputStream is = Files.newInputStream(sourceZip); ZipInputStream zis = new ZipInputStream(is))  ZipEntry entry = zis.getNextEntry(); while (entry != null)  Path path = root.resolve(entry.getName()).normalize(); if (!path.startsWith(root))  throw new IOException("Invalid ZIP"); > if (entry.isDirectory())  Files.createDirectories(path); > else  try (OutputStream os = Files.newOutputStream(path))  byte[] buffer = new byte[1024]; int len; while ((len = zis.read(buffer)) > 0)  os.write(buffer, 0, len); > > > entry = zis.getNextEntry(); > zis.closeEntry(); > > 

Now, if you are interested in the complete version, let my explain the longer story for you.

Usage

My unzip command implementation uses the builder pattern so that you can pass arguments as named parameters before launching the unzip command. There are currently 3 parameters:

Parameter Description
sourceZip (REQUIRED) Source filepath to unzip.
targetDir (REQUIRED) Target directory where the unzipped files should be placed. The given input has to be an existing directory.
bufferSize (OPTIONAL) Byte-size for the unzip buffer. The value must be positive. Default to 1024 bytes.

Here are two examples of usage:

UnzipCommand cmd = UnzipCommand.newBuilder() .sourceZip(sourceZip) .targetDir(targetDir) .build(); cmd.exec(); 
UnzipCommand cmd = UnzipCommand.newBuilder() .sourceZip(sourceZip) .targetDir(targetDir) .bufferSize(2048) // optional .build(); cmd.exec(); 

Any I/O failure will be thrown as I/O exception ( java.io.IOException ).

Implementation

Here is my implementation (see it on GitHub):

package io.mincongh.io; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** * @author Mincong Huang * @since 0.1 */ public class UnzipCommand  public static Builder newBuilder()  return new Builder(); > public static class Builder  private Path targetDir; private Path sourceZip; private int byteSize = 1024; private Builder() <> /** * (REQUIRED) Source filepath to unzip. * * @param zip the filepath to unzip * @return this */ public Builder sourceZip(Path zip)  this.sourceZip = zip; return this; > /** * (REQUIRED) Target directory where the unzipped files should be placed. The given input has to * be an existing directory. * * 

Example: Unzipping "/source/foo.zip" to target directory "/target/", the results will be * found in directory "/target/foo/". * * @param dir existing target directory * @return this */ public Builder targetDir(Path dir) this.targetDir = dir; return this; > /** * (OPTIONAL) Byte size for the unzip buffer. The value must be positive. Default to 1024 bytes. * * @param byteSize byte size for the unzip buffer * @return this */ public Builder bufferSize(int byteSize) this.byteSize = byteSize; return this; > public UnzipCommand build() Objects.requireNonNull(sourceZip); Objects.requireNonNull(targetDir); if (byteSize 0) throw new IllegalArgumentException("Required positive value, but byteSize o">+ byteSize); > return new UnzipCommand(this); > > private final int byteSize; private final Path sourceZip; private final Path targetDir; private UnzipCommand(Builder builder) this.byteSize = builder.byteSize; this.sourceZip = builder.sourceZip; this.targetDir = builder.targetDir; > /** * Execute the unzip command. * * @throws IOException if any I/O error occurs */ public void exec() throws IOException Path root = targetDir.normalize(); try (InputStream is = Files.newInputStream(sourceZip); ZipInputStream zis = new ZipInputStream(is)) ZipEntry entry = zis.getNextEntry(); while (entry != null) Path path = root.resolve(entry.getName()).normalize(); if (!path.startsWith(root)) throw new IOException("Invalid ZIP"); > if (entry.isDirectory()) Files.createDirectories(path); > else try (OutputStream os = Files.newOutputStream(path)) byte[] buffer = new byte[byteSize]; int len; while ((len = zis.read(buffer)) > 0) os.write(buffer, 0, len); > > > entry = zis.getNextEntry(); > zis.closeEntry(); > > >

In my implementation, the file input stream and ZIP input stream are used to read and extract entries. They are automatically and safely closed at the end using the try-with-resources statement. Each entry in the ZIP file is considered as a ZIP entry ( java.util.zip.ZipEntry ) and is visited using ZIP input stream. The entry list will be exhausted when all entries are visited once. In other words, the list will be exhauste when the next entry will be null. Note that ZIP entry can be either a directory or a regular file, they need to be treated differently. The size of the output buffer (byte array) is controlled by the parameter bufferSize . It defaults to 1024 bytes.

lang: en Update: my friend Florent Guillaume pointed out that the previous version was vulnerable for Zip Slip attack. Now the source code has been updated and the problem has been fixed.

Limitations

  • The file permissions are not preserved. When the ZIP file contains an executable entry, such as rwxr-xr-x , the access permission for the executable is lost.
  • The source code is tested manually on Windows (Windows 10), because Travis CI does not support Windows build for Java project. Let me know if there is any bug.

Conclusion

Today, we saw how to unzip a ZIP file in Java 8+ using java.util.zip.* , more precisely using Zip Entry and Zip Input Stream. The source code is available on GitHub in mincong-h/java-examples as UnzipCommand.java. Interested to know more about Java? You can subscribe to my feed, follow me on Twitter or GitHub. Hope you enjoy this article, see you the next time!

References

  • Pankaj, “Java Unzip File Example”, JournalDev, 2019. https://www.journaldev.com/960/java-unzip-file-example
  • Baeldung, “Zipping and Unzipping in Java”, Baeldung, 2019. https://www.baeldung.com/java-compress-and-uncompress
  • Lokesh Gupta, “Java — Unzip File with Sub-directories”, HowToDoInJava, 2019. https://howtodoinjava.com/java/io/unzip-file-with-subdirectories/
  • Mkyong, “How to decompress files from a ZIP file”, Mkyong, 2010. https://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/
  • Waypoint, “Java ZIP — how to unzip folder?”, StackOverflow, 2012. https://stackoverflow.com/questions/10633595/java-zip-how-to-unzip-folder

Источник

Unzip Files in Java

Unzip Files in Java

We can use the built-in Zip API in Java to extract a zip file. This tutorial demonstrates how to extract a zip file in Java.

Unzip Files in Java

The java.util.zip is used to unzip the zip files in Java. The ZipInputStream is the main class used to read the zip files and extract them.

Follow the steps below to extract zip files in Java.

Read the zip file using ZipInputStream and FileInputStream .
Read the entries using getNextEntry() method.
Now read the binary data using the read() method with bytes.
Close the entry using closeEntry() method.
Finally, close the zip file.

We created a function to take the input and destination path and extract the files to implement these steps. The zip file is below.

Zip File

Let’s implement the above method in Java to extract the zip file shown in the picture.

package delftstack;  import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;  public class Java_Unzip   private static final int BUFFER_SIZE = 4096;  public static void unzip(String ZipFilePath, String DestFilePath) throws IOException   File Destination_Directory = new File(DestFilePath);  if (!Destination_Directory.exists())   Destination_Directory.mkdir();  >  ZipInputStream Zip_Input_Stream = new ZipInputStream(new FileInputStream(ZipFilePath));  ZipEntry Zip_Entry = Zip_Input_Stream.getNextEntry();   while (Zip_Entry != null)   String File_Path = DestFilePath + File.separator + Zip_Entry.getName();  if (!Zip_Entry.isDirectory())    extractFile(Zip_Input_Stream, File_Path);  > else    File directory = new File(File_Path);  directory.mkdirs();  >  Zip_Input_Stream.closeEntry();  Zip_Entry = Zip_Input_Stream.getNextEntry();  >  Zip_Input_Stream.close();  >   private static void extractFile(ZipInputStream Zip_Input_Stream, String File_Path) throws IOException   BufferedOutputStream Buffered_Output_Stream = new BufferedOutputStream(new FileOutputStream(File_Path));  byte[] Bytes = new byte[BUFFER_SIZE];  int Read_Byte = 0;  while ((Read_Byte = Zip_Input_Stream.read(Bytes)) != -1)   Buffered_Output_Stream.write(Bytes, 0, Read_Byte);  >  Buffered_Output_Stream.close();  >   public static void main (String[] args) throws IOException   String ZipFilePath = "delftstack.zip";  String DestFilePath = "C:\\Users\\Sheeraz\\eclipse-workspace\\Demos";  unzip(ZipFilePath, DestFilePath);  System.out.println("Zip File extracted Successfully");  >  > 

The output for the code above is below.

Источник

Оцените статью