Note that Java 9 allows to simplify the solution of Adam Siemion’s answer significantly:
private static byte[] zipIntoByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try(ZipOutputStream zip = new ZipOutputStream(outputStream); inputStream) {
zip.putNextEntry(new ZipEntry("file"));
inputStream.transferTo(zip);
}
return outputStream.toByteArray();
}
The first changes are not Java 9 specific, you can manage both streams with a single try
statement and you don’t need to close the last (sole) zip entry as it will get closed automatically when the stream is closed. Then, Java 9 allows you to specify an existing variable like inputStream
without declaring another variable in the try
statement. Further, you can use transferTo
to transfer all remaining data from an InputStream
to an OutputStream
, without the need to implement a copying routine.
As said by Izruo in this comment when you don’t need the data in the zip file format and only want to hold a single file, you can get rid of the zip file specific overhead by using the DEFLATE
algorithm directly. We could do this similar to the solution above, just replacing ZipOutputStream
with DeflaterOutputStream
, but there’s another alternative, using DeflaterInputStream
to compress the data right when reading:
private static byte[] compressIntoByteArray(InputStream inputStream) throws IOException {
try(DeflaterInputStream deflate = new DeflaterInputStream(inputStream)) {
return deflate.readAllBytes();
}
}
When you have the array containing the compressed data, you can use new InflaterInputStream(new ByteArrayInputStream(array))
to get an InputStream
decompressing on the fly, replicating the data of the original input stream.