Is there any way to check if InputStream has been gzipped? Here\'s the code:
public static InputStream decompressStream(InputStream input) {
try {
I found this useful example that provides a clean implementation of isCompressed()
:
/*
* Determines if a byte array is compressed. The java.util.zip GZip
* implementation does not expose the GZip header so it is difficult to determine
* if a string is compressed.
*
* @param bytes an array of bytes
* @return true if the array is compressed or false otherwise
* @throws java.io.IOException if the byte array couldn't be read
*/
public boolean isCompressed(byte[] bytes)
{
if ((bytes == null) || (bytes.length < 2))
{
return false;
}
else
{
return ((bytes[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (bytes[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8)));
}
}
I tested it with success:
@Test
public void testIsCompressed() {
assertFalse(util.isCompressed(originalBytes));
assertTrue(util.isCompressed(compressed));
}
Not exactly what you are asking but could be an alternative approach if you are using HttpClient:
private static InputStream getInputStream(HttpEntity entity) throws IOException {
Header encoding = entity.getContentEncoding();
if (encoding != null) {
if (encoding.getValue().equals("gzip") || encoding.getValue().equals("zip") || encoding.getValue().equals("application/x-gzip-compressed")) {
return new GZIPInputStream(entity.getContent());
}
}
return entity.getContent();
}
The InputStream comes from HttpURLConnection#getInputStream()
In that case you need to check if HTTP Content-Encoding
response header equals to gzip
.
URLConnection connection = url.openConnection();
InputStream input = connection.getInputStream();
if ("gzip".equals(connection.getContentEncoding())) {
input = new GZIPInputStream(input);
}
// ...
This all is clearly specified in HTTP spec.
Update: as per the way how you compressed the source of the stream: this ratio check is pretty... insane. Get rid of it. The same length does not necessarily mean that the bytes are the same. Let it always return the gzipped stream so that you can always expect a gzipped stream and just apply GZIPInputStream
without nasty checks.
This is how to read a file that CAN BE gzipped:
private void read(final File file)
throws IOException {
InputStream stream = null;
try (final InputStream inputStream = new FileInputStream(file);
final BufferedInputStream bInputStream = new BufferedInputStream(inputStream);) {
bInputStream.mark(1024);
try {
stream = new GZIPInputStream(bInputStream);
} catch (final ZipException e) {
// not gzipped OR not supported zip format
bInputStream.reset();
stream = bInputStream;
}
// USE STREAM HERE
} finally {
if (stream != null) {
stream.close();
}
}
}