如何用C++中的libbz2压缩一个目录

10

我需要在C++中创建一个目录的tarball,并使用bz2进行压缩。有没有关于如何使用libtar和libbz2的不错教程?

2个回答

15

好的,我为您准备了一个快速示例。没有错误检查和各种任意决策,但它可以工作。libbzip2有相当不错的网络文档。libtar则没有那么多,但是软件包中有man页面、示例和已记录的头文件。下面的代码可以使用g++ C++TarBz2.cpp -ltar -lbz2 -o C++TarBz2.exe构建:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <libtar.h>
#include <bzlib.h>
#include <unistd.h>

int main()
{
    TAR *pTar;
    char tarFilename[] = "file.tar";
    char srcDir[] = "dirToZip/";
    char extractTo[] = ".";
    
    tar_open(&pTar, tarFilename, NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU);
    tar_append_tree(pTar, srcDir, extractTo);
    
    close(tar_fd(pTar));

    int tarFD = open(tarFilename, O_RDONLY);

    char tbz2Filename[] =  "file.tar.bz2";
    FILE *tbz2File = fopen(tbz2Filename, "wb");
    int bzError;
    const int BLOCK_MULTIPLIER = 7;
    BZFILE *pBz = BZ2_bzWriteOpen(&bzError, tbz2File, BLOCK_MULTIPLIER, 0, 0);
   
    const int BUF_SIZE = 10000;
    char* buf = new char[BUF_SIZE];
    ssize_t bytesRead;
    while((bytesRead = read(tarFD, buf, BUF_SIZE)) > 0) {
        BZ2_bzWrite(&bzError, pBz, buf, bytesRead);
    }        
    BZ2_bzWriteClose(&bzError, pBz, 0, NULL, NULL);
    close(tarFD);
    remove(tarFilename);

    delete[] buf;

}

1

假设这不仅仅是一个“我该如何做到这一点”的问题,那么显而易见的方法是分叉/执行GNU tar来为您完成。最简单的方法是使用system(3)库例程:

  system("/path/to/gtar cfj tarballname.tar.bz2 dirname");

根据this,libtar disty中有示例程序。
Bzip的文档包括一个关于使用libbz2进行编程的部分。

1
为什么这是显而易见的方法?如果他频繁这样做,进程开销会变得很大。更不用说这种方式可以完全控制bzip的选项了。当然,在调用系统时最好确保正确转义参数。 - Matthew Flaschen
1
因为它很简单,只做必要的事情,并且完全不受tar格式等任何细节的影响。在UNIX机器上,至少fork/exec是相对便宜的。所以,“显而易见”是指“什么是最简单的可行方案?” - Charlie Martin
请求是针对libbz2的,而不是通过fork/exec调用tar/bzip2来完成任务。 - hd1
使用 system 是一个糟糕的想法。这里有更多细节:http://www.cplusplus.com/forum/articles/11153/ - Tibi
1
不要教你的祖母怎么吸鸡蛋,孙子。system(3)是执行子进程最简单、最直接的方法。是的,它会fork两次:那又怎样?Fork/exec很便宜。与一个大型tar的处理时间相比,它微不足道。此外,例如(cd ~; ls)做了什么?它forks三次并执行两个exec。整个“system是邪恶的”事情每隔一段时间就会出现,因为又有一代业余爱好者开始认为他们比Ken Thompson聪明。 - Charlie Martin
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接