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.
Here is an example of how to use the DeflatorOutputStream to compress a byte array.
static byte[]compressBArray(byte[]bArray) throws IOException{ ByteArrayOutputStream os=new ByteArrayOutputStream(); try(DeflaterOutputStream dos=new DeflaterOutputStream(os)){ dos.write(bArray); } return os.toByteArray(); }
byte[] 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'
public static byte[] decompress(byte[] compressedTxt) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); try (OutputStream ios = new InflaterOutputStream(os)) { ios.write(compressedTxt); } return os.toByteArray(); }
This prints the original 'input' string.
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 arrayString b64Compressed = new String(Base64.getEncoder().encode(bytes)); byte[] decompressedBArray = Base64.getDecoder().decode(b64Compressed); //convert to original string if input was stringnew String(decompressedBArray, StandardCharsets.UTF_8);
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.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(); } }
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.