I am trying to write a class that can compress data. The below code fails (no exception is thrown, but the target .gz file is empty.)
Besides: I don't want to generate the .gz file directly like it is done in all examples. I only want to get the compressed
data, so that I can e.g. encrypt it before writting the data to a file.
If I write directly to a file everything works fine:
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
GZIPOutputStream zipStream = null;
FileOutputStream fileStream = null;
try
{
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
zipStream = new GZIPOutputStream(fileStream);
zipStream.write(dataToCompress);
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
But, if I want to 'bypass' it to the byte array stream it does not produce a single byte - compressedData
is always empty.
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
byte[] compressedData = null;
GZIPOutputStream zipStream = null;
ByteArrayOutputStream byteStream = null;
FileOutputStream fileStream = null;
try
{
byteStream = new ByteArrayOutputStream(dataToCompress.length);
zipStream = new GZIPOutputStream(byteStream);
zipStream.write(dataToCompress);
compressedData = byteStream.toByteArray();
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ byteStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
Try with this code..
Also may be helpful this one..
The problem is that you are not closing the
GZIPOutputStream
. Until you close it the output will be incomplete.You just need to close it before reading the byte array. You need to reorder the
finally
blocks to achieve this.I do not recommend inititalizing the stream variables to
null
, because it means yourfinally
block can also throw aNullPointerException
.Also note that you can declare
main
to throwIOException
(then you would not need the outermosttry
statement.)There is little point in swallowing exceptions from
zipStream.close();
, because if it throws an exception you will not have a valid .gz file (so you should not proceed to write it.)Also I would not swallow exceptions from
byteStream.close();
but for a different reason - they should never be thrown (i.e. there is a bug in your JRE and you would want to know about that.)I've improved JITHINRAJ's code - used try-with-resources:
If you are still looking an answer you can use the below code to get the compressed byte[] using deflater and decompress it using inflater.
To compress
To uncompress
You can use the below function, it is tested and working fine.
In general, your code has serious problem of ignoring the exceptions! returning
null
or simply not printing anything in thecatch
block will make it very difficult to debugYou do not have to write the zip output to a file if you want to process it further (e.g. encrypt it), you can easily modify the code to write the output to in-memory stream