Java includes built‑in classes for ZLIB compression — no extra libraries needed. The `Deflater` class does the heavy lifting, while `DeflaterOutputStream` wraps an output stream to compress data as it’s written. For decompression, there’s the matching `Inflater` and `InflaterOutputStream`. In this post, I’ll walk you through compressing a byte array, decompressing it back, and converting the result to Base64 for easy transport.
Compression
Let’s start with a static method that compresses a byte array using `DeflaterOutputStream`.
static 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:
byte[] input = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" .getBytes();
byte[] op = CompressionUtil.compressBArray(input);
System.out.println("original data length " + input.length +
", compressed data length " + op.length);
Run it and you’ll see: **original data length 71, compressed data length 12**. That’s the power of ZLIB — repetitive data shrinks dramatically.
Decompression
Let's test:
public static byte[] decompress(byte[] compressedTxt) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try (OutputStream ios = new InflaterOutputStream(os)) {
ios.write(compressedTxt);
}
return os.toByteArray();
}
When you feed the compressed bytes into this method, you’ll get back the original `'input'` string — just as expected.
Let's convert the byte[] to Base64 to make it portable
The compressed output is a raw `byte[]`, which isn’t friendly for JSON, databases, or simple file storage. Base64 encoding turns it into a safe string that can travel anywhere.
byte[] bytes = {}; //the byte array
String b64Compressed = new String(Base64.getEncoder().encode(bytes));
byte[] decompressedBArray = Base64.getDecoder().decode(b64Compressed);
//convert to original string if input was string
new String(decompressedBArray, StandardCharsets.UTF_8);
One thing to keep in mind: Base64 encoding adds about 33% in size to the already compressed data. But for storage and transport it’s well worth the trade‑off.
Here's the complete code and the test cases
**Full utility class:**
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();
}
}
**Test cases to verify everything works:**
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: Because `compress` and `decompress` work on `byte[]`, you can apply them to any binary data — images, serialized objects, you name it. Just wrap the logic into a small utility and you’re good to go.