java.util.zip.GZIPOutputStream
does not provide a constructor argument or a setter for the compression level of its underlying Deflater
.
There are ways to work around this issue, as described here, for example:
GZIPOutputStream gzip = new GZIPOutputStream(output) {
{
this.def.setLevel(Deflater.BEST_COMPRESSION);
}
};
I GZIPped a 10G file with this and its size didn't decrease by a single bit compared to using the presetDEFAULT_COMPRESSION.
The answer to this question says that under certain circumstances setting the level might not work as planned. Just to make sure, I also tried to create a new Deflater
:
this.def = new Deflater(Deflater.BEST_COMPRESSION, true);
But sill no reduction in file size...
Is there a reason why they did not provide access to the Deflater
level?
Or is something wrong with the code sample above?
Does the deflater level work at all?
Edit: Thanks for the comments.
-
Can the file be compressed any further?
It's a UTF-8 text file that is compressed from 10G to 10M using Default compression. So without knowing details about the compression levels, I reckoned it could be compressed further.
-
Time difference between
DEFAULT_COMPRESSION
andBEST_COMPRESSION
?I don't have time to create really reliable figures. But I executed the code with each compression level about five times and both take about the same time (2 minutes +/- 5 seconds).
-
File size with
gzip -v9
? The file created by gzip is about 15KB smaller than the one created by java. So, for my specific use case it's not worth investigating this topic any further.
However, the three fundamental questions stated above still persist. Anyone ever successfully decreased a file using higher compression levels with GZIPOutputStream
?
压缩:
private static String compress(String input) throws IOException {
if (StringUtil.isBlank(input)) {
return input;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out){
{
this.def.setLevel(Deflater.BEST_COMPRESSION);
}
};
gzip.write(input.getBytes());
gzip.close();
return out.toString("ISO-8859-1");
}
解压缩:
public static String uncompress(String input) throws IOException {
if (input == null || input.length() == 0) {
return input;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes("ISO-8859-1"));
GZIPInputStream ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
// toString()使用平台默认编码,也可以显式的指定如toString("GBK")
String output = out.toString();
ungzip.close();
in.close();
out.close();
return output;
}