Showing posts with label unzip. Show all posts
Showing posts with label unzip. Show all posts

Thursday, January 20, 2022

How to unzip the zip file and zip the folder in Java

In this tutorial, we are going to learn how to zip the given folder and unzip the zip file using Java.

Zip the folder or directory:

Let's create a java class ZipUnzip.java and create the main method.

public static void main(String[] args) {
        String folderInputPath = "path/of/folder/to/zip";
        String outputPath = "output/path/compressed.zip";
        try {
            zip(folderInputPath, outputPath);
        } catch (IOException e) {
            System.out.println("Error due to: " + e.getMessage());
        }
    }

Now, create a method to zip the folder.

private static void zip(String folderInputPath, String outputPath) throws IOException {
        Path sourceFolderPath = Paths.get(folderInputPath);
        File zipPath = new File(outputPath);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath));
        Files.walkFileTree(sourceFolderPath, new SimpleFileVisitor<Path>() {
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(sourceFolderPath.relativize(file).toString()));
                Files.copy(file, zos);
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }
        });
        zos.close();
    }

We are using java standard core library classes to zip. Files.walkFileTree() is used to navigate recursively through the directory tree. Once we execute the code we can see the zip file is created inside the output path provided. We can verify the compression manually by extracting it.

Unzip the zip file:

Let's create a method unzip() for unzipping the compressed file

 public static void main(String[] args) {
        String zipFilePath = "zip/file/path/compressed.zip";
        String zipOutputPath = "output/path/to/unzip";
        try {
            unzip(zipFilePath, zipOutputPath);
        } catch (IOException e) {
            System.out.println("Error due to: " + e.getMessage());
        }
    }
private static void unzip(String zipFilePath, String outputDir) throws IOException {
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(outputDir + File.separator, zipEntry.getName());
            if (zipEntry.isDirectory()) {
                if (!newFile.isDirectory() && !newFile.mkdirs()) {
                    throw new IOException("Failed to create directory " + newFile);
                }
            } else {
                File parent = newFile.getParentFile();
                if (!parent.isDirectory() && !parent.mkdirs()) {
                    throw new IOException("Failed to create directory " + parent);
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                int len = 0;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
            }
            zipEntry = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();
    }

Here, we are using ZipInputStream to read the file and FileOutputStream to write the file to the provided output directory.

The overall code implementation looks like below:

package io;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUnzip {

    public static void main(String[] args) {
        String folderInputPath = "path/of/folder/to/zip";
        String outputPath = "output/path/compressed.zip";

        String zipFilePath = "zip/file/path/compressed.zip";
        String zipOutputPath = "output/path/to/unzip";
        try {
            zip(folderInputPath, outputPath);
            unzip(zipFilePath, zipOutputPath);
        } catch (IOException e) {
            System.out.println("Error due to: " + e.getMessage());
        }
    }

    private static void zip(String folderInputPath, String outputPath) throws IOException {
        Path sourceFolderPath = Paths.get(folderInputPath);
        File zipPath = new File(outputPath);
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath));
        Files.walkFileTree(sourceFolderPath, new SimpleFileVisitor<Path>() {
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(sourceFolderPath.relativize(file).toString()));
                Files.copy(file, zos);
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }
        });
        zos.close();
    }

    private static void unzip(String zipFilePath, String outputDir) throws IOException {
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(outputDir + File.separator, zipEntry.getName());
            if (zipEntry.isDirectory()) {
                if (!newFile.isDirectory() && !newFile.mkdirs()) {
                    throw new IOException("Failed to create directory " + newFile);
                }
            } else {
                File parent = newFile.getParentFile();
                if (!parent.isDirectory() && !parent.mkdirs()) {
                    throw new IOException("Failed to create directory " + parent);
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                int len = 0;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
            }
            zipEntry = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();
    }
}
Share:

Saturday, January 8, 2022

How to unzip all the zip files present in folder and sub folders using java

In this tutorial, we are going to learn how we can unzip all the zip files present in the folder and sub-folders.

Steps to follow:

  • loop through the folder and subfolders and get the files inside it.
  • Check if the file is a zip file or not
  • If the file is a zip file then extract that file in the corresponding folder

Create a java class called UnzipFolderFile.java. First, let's implement the method which will loop through the folder and subfolders and read the zip file.

public static void searchZipFile(String directoryName) throws IOException {
        File directory = new File(directoryName);
        File[] fList = directory.listFiles();
        if (fList != null)
            for (File file : fList) {
                if (file.isDirectory()) {
                    searchZipFile(file.getAbsolutePath());
                } else if (file.isFile()) {
                    String ext = getFileExtension(file.getName());
                    if (ext.equals(".zip")) {
                        System.out.println("Zip file found");
                        String zipFilePath = file.getAbsolutePath();
                        String unZipOutputPath = getFileNameWithoutExtension(zipFilePath); // using apache commons i.o library
                        unzipFile(zipFilePath, unZipOutputPath);
                        searchZipFile(unZipOutputPath); // for nested zip file
                    }
                }
            }
    }

Here, we are using the recursion in order to search zip files inside sub-folders. If the current file is a directory then it will again search inside this directory. If it is a zip file then it will unzip that file. 

Note that we need to extract the nested zip file i.e zip file inside zip file case so, we used searchZipFile(unZipOutputPath); recursion.

In order to get the current folder, we are using the getFileNameWithoutExtension method which we gonna implement later. Now, let's implement the unzipFile method getFileExtension to get the extension of the file in order to test the current file is a zip file or not

 public static String getFileExtension(String fileName) {
        int lastIndexOf = fileName.lastIndexOf(".");
        if (lastIndexOf == -1) {
            return ""; // empty extension
        }
        return fileName.substring(lastIndexOf).toLowerCase();
    }
public static void unzipFile(String zipFilePath, String outputDir) throws IOException {
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(outputDir + File.separator, zipEntry.getName());
            if (zipEntry.isDirectory()) {
                if (!newFile.isDirectory() && !newFile.mkdirs()) {
                    throw new IOException("Failed to create directory " + newFile);
                }
            } else {
                File parent = newFile.getParentFile();
                if (!parent.isDirectory() && !parent.mkdirs()) {
                    throw new IOException("Failed to create directory " + parent);
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                int len = 0;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
            }
            zipEntry = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();
    }

This method accepts the zip file path and output path to unzip and extract the zip file and output it in the output directory provided.

Now, create getFileNameWithoutExtension method to get the directory path. For this, we are using org.apache.commons.io library. For this, load the jar file in your IDE, or if you have existing projects like Maven or Gradle add the dependency as below.

For Gradle:

Add in build.gradle under "dependencies"

implementation 'org.apache.directory.studio:org.apache.commons.io:2.4'

For Maven:

Add in pom.xml

<dependency>
  <groupId>org.apache.directory.studio</groupId>
  <artifactId>org.apache.commons.io</artifactId>
  <version>2.4</version>
</dependency>
public static String getFileNameWithoutExtension(String name) {
        return FilenameUtils.removeExtension(name);
    }

Now, implement the main method to execute the program

public static void main(String[] args) {
        String directory = "path-to-folder";
        try {
            searchZipFile(directory);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

The overall implementation looks as below:

package io;

import org.apache.commons.io.FilenameUtils;

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 UnzipFolderFile {
    public static void main(String[] args) {
        String directory = "path-to-folder";
        try {
            searchZipFile(directory);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void searchZipFile(String directoryName) throws IOException {
        File directory = new File(directoryName);
        File[] fList = directory.listFiles();
        if (fList != null)
            for (File file : fList) {
                if (file.isDirectory()) {
                    searchZipFile(file.getAbsolutePath());
                } else if (file.isFile()) {
                    String ext = getFileExtension(file.getName());
                    if (ext.equals(".zip")) {
                        System.out.println("Zip file found");
                        String zipFilePath = file.getAbsolutePath();
                        String unZipOutputPath = getFileNameWithoutExtension(zipFilePath); // using apache commons i.o library
                        unzipFile(zipFilePath, unZipOutputPath);
                        searchZipFile(unZipOutputPath); // for nested zip file
                    }
                }
            }
    }

    public static void unzipFile(String zipFilePath, String outputDir) throws IOException {
        byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(outputDir + File.separator, zipEntry.getName());
            if (zipEntry.isDirectory()) {
                if (!newFile.isDirectory() && !newFile.mkdirs()) {
                    throw new IOException("Failed to create directory " + newFile);
                }
            } else {
                File parent = newFile.getParentFile();
                if (!parent.isDirectory() && !parent.mkdirs()) {
                    throw new IOException("Failed to create directory " + parent);
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                int len = 0;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
            }
            zipEntry = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();
    }

    public static String getFileExtension(String fileName) {
        int lastIndexOf = fileName.lastIndexOf(".");
        if (lastIndexOf == -1) {
            return ""; // empty extension
        }
        return fileName.substring(lastIndexOf).toLowerCase();
    }

    public static String getFileNameWithoutExtension(String name) {
        return FilenameUtils.removeExtension(name);
    }
}
Share:

Wednesday, November 17, 2021

How to Compress(Zip) and Decompress(Unzip) byte array in Java

In this tutorial, we are going to compress and decompress the bytes array. The process may be required when serializing data as a binary file especially when the bytes array has non-unique data.

Let's create the method that compresses the bytes array.


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DeflaterOutputStream;
public static byte[] compress(byte[] bytes) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream);
        deflaterOutputStream.write(bytes);
        deflaterOutputStream.close();
        byte[] compressedBytes = byteArrayOutputStream.toByteArray();
        byteArrayOutputStream.close();
        return compressedBytes;
    }

This method will compress the bytes array. If this results in no reduction in length then the data might be unique or tend to be unique. If the data is truly unique random values then the compression might produce the greater length as well. Compression always has overhead to allow for future decompression.

Now, let's create a method that will decompress or unzip the underlying compressed data. 
import java.util.zip.InflaterInputStream;
import java.io.ByteArrayInputStream;
public static byte[] decompress(byte[] bytes) throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        InflaterInputStream inflaterInputStream = new InflaterInputStream(byteArrayInputStream);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int read;
        while ((read = inflaterInputStream.read()) != -1) {
            byteArrayOutputStream.write(read);
        }
        inflaterInputStream.close();
        byteArrayInputStream.close();
        byteArrayOutputStream.close();
        return byteArrayOutputStream.toByteArray();
    }
Let's create a test example to run these methods.

    public static void main(String[] args) {
        byte[] b = new byte[10000]; // bytes data with 0 values
        System.out.println("Initial Data Size : "+ b.length);
        try {
            byte[] compressedBytes = compress(b);
            System.out.println("Compressed Data Size : "+ compressedBytes.length);
            byte[] decompressedBytes = decompress(compressedBytes);
            System.out.println("Decompressed Data Size: "+ decompressedBytes.length);
        } catch (IOException e) {
            System.out.println("Error while zipping due to : "+e.getMessage());
        }
    }
Output:
Initial Data Size : 10000
Compressed Data Size : 33
Decompressed Data Size: 10000
There is an options to add different algorithm while doing compression using Deflater class as below
import java.util.zip.Deflater;
public static byte[] compress(byte[] bytes) throws IOException {
        Deflater deflater = new Deflater(Deflater.HUFFMAN_ONLY);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
        deflaterOutputStream.write(bytes);
        deflaterOutputStream.close();
        byte[] compressedBytes = byteArrayOutputStream.toByteArray();
        byteArrayOutputStream.close();
        return compressedBytes;
    }
Here is overall code implementation:

Zip.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import java.io.ByteArrayInputStream;

public class Zip {

    public static void main(String[] args) {
        byte[] b = new byte[10000]; // bytes data with 0 values
        System.out.println("Initial Data Size : " + b.length);
        try {
            byte[] compressedBytes = compress(b);
            System.out.println("Compressed Data Size : " + compressedBytes.length);
            byte[] decompressedBytes = decompress(compressedBytes);
            System.out.println("Decompressed Data Size: " + decompressedBytes.length);
        } catch (IOException e) {
            System.out.println("Error while zipping due to : " + e.getMessage());
        }
    }

    public static byte[] compress(byte[] bytes) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream);
        deflaterOutputStream.write(bytes);
        deflaterOutputStream.close();
        byte[] compressedBytes = byteArrayOutputStream.toByteArray();
        byteArrayOutputStream.close();
        return compressedBytes;
    }

    public static byte[] decompress(byte[] bytes) throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        InflaterInputStream inflaterInputStream = new InflaterInputStream(byteArrayInputStream);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int read;
        while ((read = inflaterInputStream.read()) != -1) {
            byteArrayOutputStream.write(read);
        }
        inflaterInputStream.close();
        byteArrayInputStream.close();
        byteArrayOutputStream.close();
        return byteArrayOutputStream.toByteArray();
    }
}
Share: