GZIPOutputStream与ByteArrayOutputStream共同使用注意事项

3 篇文章 0 订阅
2 篇文章 0 订阅

GZIPOutputStream与ByteArrayOutputStream共同使用时,先把数据存到baos,再写入文件,出现了以下错误

java.io.EOFException : Unexpected end of ZLIB input stream
       at java.util.zip.InflaterInputStream.fill( InflaterInputStream.java:240)
       at java.util.zip.InflaterInputStream.read( InflaterInputStream.java:158)
       at java.util.zip.GZIPInputStream.read( GZIPInputStream.java:117)
       at java.io.FilterInputStream.read( FilterInputStream.java:107)
       at TestGzip.main( TestGzip.java:29)

查看文件大小,与直接使用FileOutputStream写的不一致,要小很多,究其原因,是数据没有完全刷到baos中。

翻看源码发现,gzip等压缩流在close时,会调用finish方法,完成流的转换,此处使用baos,在close之前就去取值,从而导致流数据不完整。

若想提前使用baos获取全部流数据,需要手动执行finish方法,进行手动刷新。

测试代码如下:

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class TestGzip {
        public static void main(String[] args) {
              try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                           GZIPOutputStream gzip = new GZIPOutputStream(baos );
                           FileOutputStream fos = new FileOutputStream("d://1.txt" );) {
                     gzip.write( "test".getBytes("UTF-8" ));
                     //gzip 只调用flush不会刷新
                     gzip.flush();
                    
                     //压缩类型的流需要执行close或者finish才会完成
//                  gzip.finish();

                     fos.write( baos.toByteArray());
             } catch (Exception e ) {
                     e.printStackTrace();
             }

              try (InputStream in = new GZIPInputStream(new FileInputStream("d://1.txt" ));
                           FileOutputStream fos = new FileOutputStream("d://2.txt" )) {
                     int len = -1;
                     byte[] buff = new byte[4096];
                     while ((len = in .read(buff )) > 0) {
                            fos.write( buff, 0, len);
                    }
             } catch (Exception e ) {
                     e.printStackTrace();
             }
       }
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值