How to unzip/extract files from Zip Archive in Java

Java has built in support for zipping files and unzipping the zip archives. In this tutorial i am going to extract/unzip files from a Zip archive.

I am going to use ZipFile class for this purpose. It is under package java.util.zip

The 3 classes, we will be using in this tutorial are
1. java.util.zip.ZipFile
2. java.util.zip.ZipEntry
3. java.util.zip.ZipException

ZipFile is the class that represents the zipped file in Java. So if you want to parse zipped file, you need to create an object of ZipFile class by passing location of zipped file to it.

Step 1: Creating ZipFile object.
ZipFile zFile = new ZipFile("C:\Users\sreenath\Desktop\Test.zip");

here ZipFile object is pointing to the Text.zip file.

Next is you need to get the contents of Text.zip file, you can get the contents by calling entries() method of ZipFile object, it returns all the entries of zip file as Enumeration object.

Step 2: call entries() method on ZipFile object.
Enumeration<? extends ZipEntry> entries = zFile.entries();

Step 3: Iterating the contents and saving.
Now iterate all the entries in a while loop and extract the contents to your local file system. Each content of zip file is represented by ZipEntry class. While iterating save the contents to local disk.

 Saving the entries is trickiest part here. For example, if a zip file has one directory and text/image files inside the directory, you need to first save the directory and then the text/image files inside the created directory. So the logic is 
a. If the zip entry is a directory, then create a directory and update the path accordingly
b. If the zip entry is a file then save the entry to disk. I have wrote a separate method for this purpose named saveEntry(). See step4, for explanation.

below is the code.
ZipEntry anEntry = null;

while(entries.hasMoreElements()) {

    anEntry = entries.nextElement();   

    if(!anEntry.isDirectory() ) {

        saveEntry(zFile,anEntry,newPath); // saves files which are not directories

    } else {      

        newPath += File.seperator+anEntry.getName();

    }

}

Step 4: Saving contents to disk (non directory files)
For saving a Zip Entry, we need to get the input stream for that ZipEntry from ZipFile object. The method for this purpose is getInputStrem().
InputStream in = zFile.getInputStream(anEntry);

Once you get the input stream, use the BufferedOutputStream to save it.
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(newPath + "/" + anEntry.getName()));

The method for saving the Entry is below.
     InputStream in = null;
     BufferedOutputStream fos = null;
   
     File aFile = null;
 try{
  aFile = new File(newPath +"/" + anEntry.getName());
  aFile.getParentFile().mkdirs();
  in = zFile.getInputStream(anEntry);
  fos = new BufferedOutputStream(new FileOutputStream(aFile));
  byte[] buffer = new byte[1024];
  int length;
  while((length = in.read(buffer)) > 0) {
   fos.write(buffer,0,length);
  }
  
 } finally {
  if(in != null) {
   in.close();
  }
  if(fos != null) {
   fos.close();
 }
}
   Note: This code works if the zip archive has any number of files those are non directories, and also if the zip archive has one folder and any number of non directory files inside it. The complete working code is
package com.speakingcs.zip;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class UnZipFile {

 public static void main(String[] args) {
  
  UnZipFile uzf = new UnZipFile();
  try {
   uzf.unZipFile(new File("C:/Users/A8020/Desktop/xyz.zip"));
  } catch (ZipException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 private void unZipFile(File src) throws ZipException, IOException {
  String newPath = "";
  String filePath = src.getAbsolutePath();
  ZipFile zFile = new ZipFile(src);
  new File(filePath.substring(0, filePath.lastIndexOf('.'))).mkdir();
  newPath = filePath.substring(0,filePath.lastIndexOf('.'));
  
  Enumeration entries = zFile.entries();
  
  while(entries.hasMoreElements()) {
   
   ZipEntry anEntry = entries.nextElement();
   if(!anEntry.isDirectory()) {    
    saveEntry(zFile,anEntry,newPath);
   } else { 
    newPath += File.separator+anEntry.getName();
   }
  }
  
 }

 private void saveEntry(ZipFile zFile, ZipEntry anEntry, String newPath) throws IOException {
  InputStream in = null;
  BufferedOutputStream fos = null;
   
  File aFile = null;
  try{
   aFile = new File(newPath +"/" + anEntry.getName());
   aFile.getParentFile().mkdirs();
   in = zFile.getInputStream(anEntry);
   fos = new BufferedOutputStream(new FileOutputStream(aFile));
   byte[] buffer = new byte[1024];
   int length;
   while((length = in.read(buffer)) > 0) {
    fos.write(buffer,0,length);
   }
   
  } finally {
   if(in != null) {
    in.close();
   }
   if(fos != null) {
    fos.close();
   }
  }  
 } 
}


Comments