Showing posts with label compress. Show all posts
Showing posts with label compress. Show all posts

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: