zlib 库 Linux 平台使用示例及总结

22 篇文章 0 订阅

库的安装及使用

安装库,注意其中名称中是 1g 不是 lg。

sudo apt install zlib1g-dev

代码中需要引入头文件

#include <zlib.h>

编译时需要指定库 -lz

gcc zlib_test.c -lz

程序示例

本程序基于官网源程序zpipe.c的修改而来。

#include <zlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define CHUNK 8192

int decompress_file(char *in_filename, char *out_filename)
{
    z_stream stream;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];
    int fdin, fdout;
    int have;
    int ret, flush;

    fdin = open(in_filename, O_RDONLY);
    if (fdin < 0) {
        perror(in_filename);
        return Z_ERRNO;
    }
    fdout = open(out_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (fdout < 0) {
        perror(out_filename);
        ret = Z_ERRNO;
        goto close_in;
    }

    memset(&stream, 0, sizeof(stream));
    ret = inflateInit(&stream);
    if (ret != Z_OK) 
        goto close_out;
    
    do {
        stream.avail_in = read(fdin, in, CHUNK);
        if (stream.avail_in < 0) {
            ret = Z_ERRNO;
            goto end_inflate;
        }
        if (stream.avail_in == 0)
            break;
        stream.next_in = in;

        do {
            stream.avail_out = CHUNK;
            stream.next_out = out;
            ret = inflate(&stream, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);
            switch (ret)
            {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:          
                goto end_inflate;
            }
            have = CHUNK - stream.avail_out;
            if (write(fdout, out, have) != have) {
                ret = Z_ERRNO;
                goto end_inflate;
            }
        } while(stream.avail_out == 0);

    } while(ret != Z_STREAM_END);

    ret = (ret == Z_STREAM_END) ? Z_OK : Z_DATA_ERROR;

end_inflate:
    (void) inflateEnd(&stream);
close_out:
    close(fdout);
close_in:
    close(fdin);

    return ret;
}

int compress_file(char *in_filename, char *out_filename) 
{
    z_stream stream;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];
    int fdin, fdout;
    int have;
    int ret, flush;

    fdin = open(in_filename, O_RDONLY);
    if (fdin < 0) {
        perror(in_filename);
        return Z_ERRNO;
    }
    fdout = open(out_filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (fdout < 0) {
        perror(out_filename);
        ret = Z_ERRNO;
        goto close_in;
    }

    memset(&stream, 0, sizeof(stream));
    ret = deflateInit(&stream, Z_BEST_COMPRESSION);
    if (ret != Z_OK) 
        goto close_out;
    
    do {
        stream.avail_in = read(fdin, in, CHUNK);
        if (stream.avail_in < 0) {
            ret = Z_ERRNO;
            goto end_deflate;
        }
        flush = stream.avail_in ? Z_NO_FLUSH : Z_FINISH;
        stream.next_in = in;

        do {
            stream.avail_out = CHUNK;
            stream.next_out = out;
            ret = deflate(&stream, flush);
            assert(ret != Z_STREAM_ERROR);
            have = CHUNK - stream.avail_out;
            if (write(fdout, out, have) != have) {
                ret = Z_ERRNO;
                goto end_deflate;
            }
        } while (stream.avail_out == 0);
        assert(stream.avail_in == 0);  

    } while(flush != Z_FINISH);

    ret = Z_OK;

end_deflate:
    (void) deflateEnd(&stream);
close_out:
    close(fdout);
close_in:
    close(fdin);

    return ret;
}

/* report a zlib or i/o error */
void zerr(int ret)
{
    fputs("zpipe: ", stderr);
    switch (ret) {
    case Z_ERRNO:
        if (ferror(stdin))
            fputs("error reading stdin\n", stderr);
        if (ferror(stdout))
            fputs("error writing stdout\n", stderr);
        break;
    case Z_STREAM_ERROR:
        fputs("invalid compression level\n", stderr);
        break;
    case Z_DATA_ERROR:
        fputs("invalid or incomplete deflate data\n", stderr);
        break;
    case Z_MEM_ERROR:
        fputs("out of memory\n", stderr);
        break;
    case Z_VERSION_ERROR:
        fputs("zlib version mismatch!\n", stderr);
    }
}

int main(int argc, char **argv)
{
    int ret;

    if (argc == 3) {
        ret = compress_file(argv[1], argv[2]);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }

    else if (argc == 4 && strcmp(argv[1], "-d") == 0) {
        ret = decompress_file(argv[2], argv[3]);
        if (ret != Z_OK)
            zerr(ret);
        return ret;
    }

    else {
        fputs("zpipe usage: zpipe [-d] source dest\n", stderr);
        return 1;
    }
}

结果对比

将原文件压缩,然后再解压缩,对比新文件其 sha256 是否一致。

shasum -a 256 file_name

本程序结果一致。

参考:
zlib Usage Example

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lylhw13_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值