首页 > 编程语言 >bzip2 C/C++ 库bzlib.h使用案例:读取.bz2文件

bzip2 C/C++ 库bzlib.h使用案例:读取.bz2文件

时间:2023-01-06 15:23:54浏览次数:64  
标签:bzerror bzip2 读取 bzlib BZ2 文件 gbk C++ bz2

准备

从网上下载bzip2库,我下载的是V1.0.8版本的。
然后在C工程中添加一个筛选器(文件夹)名叫bzlib,然后把下载的库中的如下9个文件,添加到其中:
image

代码

主函数代码如下:

#include <stdio.h>
#include "bzlib/bzlib.h"
int main()
{
    FILE* f;        //用来接收打开文件的句柄
    BZFILE* b;      //用来接收库函数:BZ2_bzReadOpen打开的文件
    char buf[1024]; //用来接收库函数:BZ2_bzRead读取出的字节
    int bzerror;    //用来接收库抛出的成功/错误代码
    int nOpen;      //用来接收BZ2_bzRead读取出的字节的长度
    char fileName[] = "bz2/gbk.txt.bz2";
    int stop = 1;   //停止读取文件流的标志

    f = fopen(fileName, "rb"); // 设置2进制只读
    if (f == NULL) {
        printf("文件不存在");
        return;
    }
    b = BZ2_bzReadOpen(
        &bzerror, // 错误码
        f,        // 文件指针
        0,        // 范围0-4,数字越大,monitoring/debugging输出越冗长
        1,        // 设置为不为0的数,则使用另一种压缩算法,这种算法少一半的内存消耗,代价是速度变慢
        NULL,     // 不使用
        0         // 不使用
    );
    while (stop) {
        if (bzerror == BZ_OK) // 成功打开
        {
            int num = sizeof(buf);
            nOpen = BZ2_bzRead(&bzerror, b, buf, num);
            if (bzerror == BZ_OK) { //读取成功
                for (int i = 0; i < sizeof(buf); i++) {     //以字符形式循环打印出读到的字节
                    printf("%c", buf[i]);
                }
            }
            else if (bzerror == BZ_STREAM_END) {    //读到了文件流(库手册中称为逻辑流)的末尾
                for (int i = 0; i < nOpen; i++) {   //以字符形式循环打印出读到的字节
                    printf("%c", buf[i]);
                }
                stop = 0;   //退出循环读取
            }
            else if (bzerror == BZ_MEM_ERROR)
            {
                printf("没有足够的内存可用");
            }
            else {  //其他情况
                printf("读取遇到错误,错误码:%d", bzerror);
            }
        }
        else // 打开失败立即关闭文件
        {
            BZ2_bzReadClose(&bzerror, b);
        }
    }
    //关闭文件
    BZ2_bzReadClose(&bzerror, b);
    fclose(f);
}

其中最重要的点是: BZFILE* b这个结构体接收BZ2_bzReadOpen返回的结构体,其中包含了许多的信息。我们使用BZ2_bzRead读取的话,无需关注读取的文件的大小,每次读取到了哪个字节,因为这些信息都在被BZFILE* b内部记录了,我们只需要循环调用BZ2_bzRead,把b传进去即可。它会自动往下读,我们在每次读取完成后,把缓冲区的字节拿出来即可。注意检查bzerror == BZ_MEM_ERROR,如果相等,说明读到了文件末尾。这时需要关闭循环读取。并且关闭文件。

测试

首先在工程所在的文件夹下创建一个文件夹bz2,然后使用vscode在其中创建一个文件bgk.txt,在其中输入一些文字:

中文测试:你好世界!
数字测试:123456
English:hello world!

使用vscode的原因是它能方便地改变文件的编码,所以使用其他的文本编辑器也可以。
更改这个文件为gbk编码,因为控制台输出是gbk格式。
然后使用压缩软件把gbk.txt打一个.bz2的压缩包。打包完成的文件名应该是gbk.txt.bz2,这个压缩包在bz2文件夹。上述代码中,文件名fileName[]赋值为 "bz2/gbk.txt.bz2",这样代码就能找到这个文件了。

然后执行代码,可以看到控制台输出了gbk.txt的内容,说明解压成功:
image

本文使用了libbzip2库(即bzlib.h)中高级接口的三个函数:BZ2_bzReadOpen、BZ2_bzRead、BZ2_bzReadClose。其他低级接口、高级接口、通用接口的函数暂没有使用。可详阅官方手册:https://sourceware.org/bzip2/manual/manual.html
搭配DeepL翻译使用更佳。

标签:bzerror,bzip2,读取,bzlib,BZ2,文件,gbk,C++,bz2
From: https://www.cnblogs.com/sq800/p/17030448.html

相关文章

  • C++可执行文件绝对路径获取与屏蔽VS安全检查
    :前言前几天写新项目需要用到程序所在绝对路径的时候,发现网上居然一点相关分享都没有。:_pgmptr翻箱倒柜找出了几本教程,发现了一个叫_pgmptr的东西。进去看了一下,在s......
  • C++ 文件读入速度测试
    在信息学竞赛中,输入数据规模可能会很大,这时候就需要注意文件读取的效率。本文在Linux环境下测试了C++几种常见读入方式的效率。1.系统环境ArchLinuxx86_64默认L......
  • C++中对句柄Handle的理解
    在C++的初学者中,很容易把句柄理解成指针,但其实,句柄并不是指针. 那么句柄是什么,一句话,句柄是资源(或项目)的唯一标识。我们需要搞清楚的是,句柄Handle到底是怎么来标识......
  • 【LeetCode2180】[Go/C++/C#/Ruby/Swift/Kotlin/Rust/PHP/TS/Racket/Dart/Java/Elixir
    [toc]题解地址https://leetcode.cn/problems/count-integers-with-even-digit-sum/solutions/2047123/by-yhm138_-w8co/lc2180代码//点击指定元素document.querySel......
  • 【C++高级编程】(四)设计可重用的代码
      4.1重用哲学  4.2如何设计可重用的代码  4.2.1使用抽象    4.2.2构建理想的重用代码   4.2.3 设计有用的接口    4.2.4协......
  • C++教师教学创新大赛信息管理系统
    C++教师教学创新大赛信息管理系统二、教师教学创新大赛信息管理系统基本要求1、本系统包括建立评审专家帐号、选手报名、选手比赛(评审专家评分)、结果公示与统计等环节。......
  • 【VS Code】c++环境配置 && .vscode文件 && Code Runner的exe文件指定生成位置
    因为一些奇奇怪怪的问题重装了系统,所以重新配置了vscode,上次配置vscode时由于没有用过,所以环境配置一头雾水,甚至还有些历史遗留问题,一直都是在凑活着用,这次刚好重新开始。......
  • C/C++之大端小端
    参考链接:https://blog.csdn.net/qq78442761/article/details/61210305 注释:  //此处的右移运算是对0x12345678进行操作 且4个Byte中取得是最低的一个  ......
  • C++标准库探索std::chrono
    ​​如何获取C++标准库的源码-走看看​​std::chronochrono是一个timelibrary,源于​​boost​​,现在已经是C++标准。要使用chrono库,需要 ​​​#include<chrono>​......
  • c++算法练习day01【2022年蓝桥杯省赛B组题目】每天做一点、、、
    这个练习目前来说就比较宽松,打算在寒假(基本也就是这一个月每天刷几道题吧)题目一:小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做a道题目,周六和周......