Monday, July 13, 2020

Java Compress/Decompress String/Data

Oracle Java Tutorial and Material, Oracle Java Exam Prep, Java Learning, Java Certification

Java provides the Deflater class for general purpose compression using the ZLIB compression library. It also provides the DeflaterOutputStream which uses the Deflater class to filter a stream of data by compressing (deflating) it and then writing the compressed data to another output stream. There are equivalent Inflater and InflaterOutputStream classes to handle the decompression.

Compression


Here is an example of how to use the DeflatorOutputStream to compress a byte array.

//Compress byte arraystatic byte[] compressBArray(byte [] bArray) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();    try (DeflaterOutputStream dos = new DeflaterOutputStream(os)) {
        dos.write(bArray);    }
    return os.toByteArray();}

Let’s test:

//Testingbyte[] input = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes();byte[] op = CompressionUtil.compressBArray(input);System.out.println("original data length " + input.length + ",  compressed data length " + op.length);

This results ‘original data length 71,  compressed data length 12’

Decompression


public static byte[] decompress(byte[] compressedTxt) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();    try (OutputStream ios = new InflaterOutputStream(os)) {
        ios.write(compressedTxt);    }
 
    return os.toByteArray();}

Let’s test:

byte[] input = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes();byte[] op = CompressionUtil.compress(input);
 
byte[] org = CompressionUtil.decompress(op);
System.out.println(new String(org, StandardCharsets.UTF_8));

This prints the original ‘input’ string.

Let’s convert the byte[] to Base64 to make it portable


In the above examples we are getting the compressed data in byte array format (byte []) which is an array of numbers.

But we might want to transmit the compressed data to a file or json or db right? So, in order to transmit, we can convert it to Base64 using the following

{
    byte[] bytes = {}; //the byte array     String b64Compressed = new String(Base64.getEncoder().encode(bytes));
    byte[] decompressedBArray = Base64.getDecoder().decode(b64Compressed);    new String(decompressedBArray, StandardCharsets.UTF_8); //convert to original string if input was string }

Here’s the complete code and the test cases


package compress;
import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStream;import java.nio.charset.StandardCharsets;import java.util.Base64;import java.util.zip.Deflater;import java.util.zip.DeflaterOutputStream;import java.util.zip.InflaterOutputStream;
public class CompressionUtil {
 
    public static String compressAndReturnB64(String text) throws IOException {
        return new String(Base64.getEncoder().encode(compress(text)));    }
 
    public static String decompressB64(String b64Compressed) throws IOException {
        byte[] decompressedBArray = decompress(Base64.getDecoder().decode(b64Compressed));        return new String(decompressedBArray, StandardCharsets.UTF_8);    }
 
    public static byte[] compress(String text) throws IOException {
        return compress(text.getBytes());    }
 
    public static byte[] compress(byte[] bArray) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();        try (DeflaterOutputStream dos = new DeflaterOutputStream(os)) {
            dos.write(bArray);        }
        return os.toByteArray();    }
 
    public static byte[] decompress(byte[] compressedTxt) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();        try (OutputStream ios = new InflaterOutputStream(os)) {
            ios.write(compressedTxt);        }
 
        return os.toByteArray();    }
 
}

Test case:

package compress;
import org.junit.jupiter.api.Test;
import java.io.IOException;import java.nio.charset.StandardCharsets;
public class CompressionTest {
 
    String testStr = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    @Test    void compressByte() throws IOException {
        byte[] input = testStr.getBytes();        byte[] op = CompressionUtil.compress(input);        System.out.println("original data length " + input.length + ",  compressed data length " + op.length);
        byte[] org = CompressionUtil.decompress(op);        System.out.println(org.length);        System.out.println(new String(org, StandardCharsets.UTF_8));    }
 
    @Test    void compress() throws IOException {
 
        String op = CompressionUtil.compressAndReturnB64(testStr);        System.out.println("Compressed data b64" + op);
        String org = CompressionUtil.decompressB64(op);        System.out.println("Original text" + org);
    }
 
}

Note: Since the compress and decompress method operate on byte[], we can compress/decompress any data type.

Related Posts

0 comments:

Post a Comment