Tags: code, command, crontab, enterprise, error, execute, file, format, gzip, gzipinputstream, java, line, order, perfectly, unzip, zipped
Not in GZIP format error while trying to unzip the file
I'm using GZIPInputStream in order to read data from zipped file.
It worked perfectly from command line. I have to execute the same code from crontab and it gave me the exception:
java.io.IOException: Not in GZIP format
It tries to check the GZIP_MAGIC number and for some reason failed.
The stack trace I'm getting points to GZIPInputStream constructor.
GZIPInputStream input = new GZIPInputStream( new FileInputStream( fileName));
Any help will be highly appreciated.
Leave a comment...
- 7 Comments
This may be a little late for you, but I am having the same problem. I am using an encryption package as well. I created input and output streams to wrap my encryption package. (javax.? has something similar)
Anyway, my algorithm goes:data -> gzip -> encrypt ->decrypt -> gzip ->data
If I used encryption without the gzip everything works fine, and if I use gzip without the encryption it works fine as well. But if I use them in conjuction, bad thing happen.
I copied versions of the GZIPInput and output stream classes from java.util.zip and made my own so I could put in debug code. Then I saw what was happening.GZIP writes a header of 8b1f. It does this by writing a first to 1f as a byte (this is 31 in decimal) and then the 8b (this is 139 unsigned byte or -117 signed byte).
My debug code shows that it writes 31,-117 to the stream, but reads 31,139 when I don't use encryption and 31,-117 when I do. Another strange thing about this, though, is that everywhere I have debug code, this is the only byte that prints out unsigned in my debug messages... When encryption is turned on this same debug message prints -117.
I have no idea why this is happening. To test things some more, I changed my copy of the gzipinputstream to compare this header value with the GZIP_MAGIC number (35615) and with -29921. Now everything works perfectly.There has to be a better solution for this, but I don't know what it is yet.
GZIP_MAGIC is 8b1f sent as two bytes 1f and then 8b, and then shifting the 8b.
-117, using the Integer.toString(-117,16), gives a hex of -75. Using the same methodology as above, we can get -751f which is -29921.
The header check is essentially:
if ((int)readUByte(in) << 8) | (int)readUByte(in) != GZIP_MAGIC)
So change this store the value in a variable and compare it to GZIP_MAGIC and -29921 and your problem will disappear.
I am not sure what they were thinking. readUByte is a simple read. There is nothing unsigned about it. There is probably some casting somewhere along here that is causing the error, but nothing I am doing seem incorrect.
Hope this helps. Actually, I hope you have solved your problem by now, but if not,... If you have any insights, I would appreciate hearing them.#1; Sat, 14 Jul 2007 21:11:00 GMT
I got it to work. What happens is that the gzip input stream reads using the no argument read() method which returns an it. The stream I was using to wrap this stream got the int from the decryption buffer, which is a byte array. I changed my CipherInputStream to take the value read and masked it with 0x000000ff. This should not be necessary. Java doesn't deal with unsigned variables really, so what they are messing this it hear is beyond me.#2; Sat, 14 Jul 2007 21:11:00 GMT
- > I'm using GZIPInputStream in order to read data from zipped file.However the GZIP and ZIP file formats are diffeernt!#3; Sat, 14 Jul 2007 21:11:00 GMT
- Hi Mark,I have the same problem. I read your replay but I did not understand rigth. Do you have some examples?Thanks,s,Marco#4; Sat, 14 Jul 2007 21:11:00 GMT
An alternative is to use the InflaterInputStream with an Inflater and a corresponding DeflaterOutputStream with a Deflater. This is only applicable if you are responsible for creating the compressed/encrypted file.
CipherOutputStream cipherOutput = new CipherOutputStream(someOutStream,someCiper);
DeflaterOutputStream zipOutput = null;
zipOutput = new DeflaterOutputStream(cipherOutput, new Deflater(
// ... code to copy someInStream to the zipOutput
...and to reverse the process...
CipherInputStream cipherInput = new CipherInputStream(someInStream, someCipher);
InflaterInputStream zipInput = null;
zipInput = new InflaterInputStream(cipherInput, new Inflater());
// ... code to copy zipInput to someOutStream
...try...catch blocks removed for clarity.
Hope this helps...#5; Sat, 14 Jul 2007 21:11:00 GMT
> I got it to work. What happens is that the gzip
> input stream reads using the no argument read()
> method which returns an it. The stream I was using
> to wrap this stream got the int from the decryption
> buffer, which is a byte array. I changed my
> CipherInputStream to take the value read and masked
> it with 0x000000ff.
Mark, if you're still reading this thread, were you using the JCE javax.crypto.CipherInputStream, or your own imlementation?I had a look at the JCE source, and it's doing the right thing. You said you changed your CipherInputStream, which makes me curious as to if there is a problem in JCE, or your code?
Thanks.#6; Sat, 14 Jul 2007 21:11:00 GMT
> Mark, if you're still reading this thread, were you
> using the JCE javax.crypto.CipherInputStream, or your
> own imlementation?
Good grief, I completely missed the first line of his post.
> I am using an encryption package as well. I created input and output streams
> to wrap my encryption package. (javax.? has something similar)
Yes, there is javax.crypto.CipherInputStream. :)#7; Sat, 14 Jul 2007 21:11:00 GMT