java.util.zip.ZipException:超额订阅动态位长度树

问题描述:

我使用gzip压缩字符串,然后解压结果,但是我得到以下异常,为什么?java.util.zip.ZipException:超额订阅动态位长度树

 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); 
} 
} 

根据this page,一个可能的原因是,你想读的ZIP文件已损坏。 (我知道它不是与你的情况完全匹配......但我确定异常消息是指示性的。)

就你而言,问题在于你正在从字节数组中转换gzip流到一个字符串,然后回到一个字节数组。这几乎肯定是有损操作,导致GZIP流损坏。

如果要将任意字节数组转换为字符串形式并返回,则需要使用为此设计的字符串编码格式之一;例如BASE64。

或者,只是改变这一点:

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

这样:

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