Java 8 中 GZIPInputStream 类源码分析

这是《水煮 JDK 源码》系列 的第4篇文章,计划撰写100篇关于JDK源码相关的文章

GZIPInputStream 类位于 java.util.zip 包下,继承于 InflaterInputStream 类,它实现了一个流式过滤器,主要用于读取GZIP文件格式的压缩数据,其UML类图如下:
在这里插入图片描述
类声明如下:

public class GZIPInputStream extends InflaterInputStream

1、成员变量

GZIPInputStream 定义了3个成员变量,分别如下:

/** CRC-32 用于未压缩的数据 */
protected CRC32 crc = new CRC32();
/** 表示输入流的结尾状态 */
protected boolean eos;
/** 输入流是否已关闭的状态 */
private boolean closed = false;

2、构造函数

创建 GZIPInputStream 压缩输入流主要有以下的两种方式:

/** 使用默认大小的缓冲区创建新的输入流 */
public GZIPInputStream(InputStream in) throws IOException {
   
    // 默认缓冲区大小为512
    this(in, 512);
}

/** 使用指定大小的缓冲区创建新的输入流 */
public GZIPInputStream(InputStream in, int size) throws IOException {
   
    // 调用父类 InflaterInputStream 的构造函数
    super(in, new Inflater(true), size);
    // 设置父类 InflaterInputStream 的 usesDefaultInflater
    // 表示使用默认的解压缩器
    usesDefaultInflater = true;
    // 读取 GZIP 的成员头信息,并返回头信息的总字节数
    readHeader(in);
}

由于 GZIPInputStream 是由于读取压缩数据的输入流,因此需要用到解压缩器 Inflater

3、读取数据方法

GZIPInputStream 主要提供了1个用于读取流数据的方法,如下:

public int read(byte[] buf, int off, int len) throws IOException {
   
    // 在正式读取流数据之前,要确保流没有被关闭
    ensureOpen();
    // 如果已经到了流的结尾,说明没有可读的数据了,直接返回 -1
    if (eos) {
   
        return -1;
    }
    // 调用父类 InflaterInputStream 的 read() 方法读取数据
    int n = super.read(buf, off, len);
    // 如果实际读取到的数据为 -1,说明没有可读数据
    if (n == -1) {
   
        // 读取 GZIP 的成员尾部信息,判断是否读取到了 eos
        // 如果是,则将 eos 置为 true,表示已读取到了尾部
        if (readTrailer())
            eos = true;
        else
            // 否则,继续调用本方法进行读取
            return this.read(buf, off, len);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值