tags:

views:

117

answers:

1

I am compressing a string using gzip, then uncompress the result, however I got the following exception, why?

 output:
Exception in thread "main" java.util.zip.ZipException: oversubscribed dynamic bit lengths tree
 at java.util.zip.InflaterInputStream.read(Unknown Source)
 at java.util.zip.GZIPInputStream.read(Unknown Source)
 at Test.main(Test.java:25)
‹
public class Test {
 public static void main(String[]args) throws IOException{
  String s="helloworldthisisatestandtestonlydsafsdafdsfdsafadsfdsfsdfdsfdsfdsfdsfsadfdsfdasfassdfdfdsfdsdssdfdsfdsfd";
  byte[]bs=s.getBytes();
  ByteArrayOutputStream outstream = new ByteArrayOutputStream();

  GZIPOutputStream gzipOut = new GZIPOutputStream(outstream);
  gzipOut.write(bs);
  gzipOut.finish();
  String out=outstream.toString();
  System.out.println(out);
  System.out.println(out.length());

  ByteArrayInputStream in = new ByteArrayInputStream(out.getBytes());
  GZIPInputStream gzipIn=new GZIPInputStream(in);
  byte[]uncompressed = new byte[100000];
  int len=10, offset=0, totalLen=0;
  while((len = gzipIn.read(uncompressed, offset, len)) >0){ // this line
   offset+=len;
   totalLen+=len;
  }

  String uncompressedString=new String(uncompressed,0,totalLen);
  System.out.println(uncompressedString);
 }
}
+1  A: 

According to this page, a likely cause is that the ZIP file you are trying to read is corrupted. (I know it is not an exact match to your circumstances ... but I'm sure that the exception message is indicative.)

In your case, the problem is that you are converting the gzip stream from a byte array into a String and then back to a byte array. This is almost certainly a lossy operation, resulting a corrupted GZIP stream.

If you want to convert an arbitrary byte array to a string form and back, you will need to use one of the string encoding formats designed for that purpose; e.g. base64.

Alternatively, just change this:

    String out = outstream.toString();
    ByteArrayInputStream in = new ByteArrayInputStream(out.getBytes());

to this:

    byte[] out = outstream.toByteArray();
    ByteArrayInputStream in = new ByteArrayInputStream(out);
Stephen C