【问题标题】:How to I compress a tarball with gzip?如何使用 gzip 压缩 tarball?
【发布时间】:2011-02-14 02:03:44
【问题描述】:

嘿,我想知道是否有人知道如何使用 gzip 压缩 tarball 文件。我已经检查了this 并成功压缩了一个 tarball,尽管我想用 gzip 而不是 libbz2 压缩那个 tarball。

我还尝试从zlib source code. 的gzappend.c 示例中实现gztack 函数,但最终得到了一堆错误和弃用的警告,所以我想我不会从一个弃用的例子中得到太多.

有谁知道我如何实现这一点,最好是使用 zlib 库?

【问题讨论】:

  • 到目前为止,最简单的方法是在创建 tar 文件时将 z 选项传递给 tar。你想用 C++ 做这件事的动机是什么?
  • 我的动机是我希望这是跨平台的,通常在其他平台上他们不会在系统中安装 tar。
  • 哪些linux平台没有tar?
  • 不确定,我只是将 linux 作为标签,因为这是我目前正在使用的,我将来可能会使用 Windows/Mac。使用系统调用似乎并不正确,即使您确定要为其开发它的大多数平台都应该拥有它。
  • @Sam 回到青铜时代,一些单盘和双盘系统没有 gnutar,您必须单独压缩它们。除此之外,我一无所知。

标签: c++ linux gzip tar zlib


【解决方案1】:

使用zlib 例程gzopen 打开压缩流,gcwrite 向其中写入数据并对其进行压缩,gzclose 用于关闭它。这是一个将一个文件压缩到另一个文件的完整程序:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>

int main(int argc, char **argv)
{
  if(argc < 3)
  {
    fprintf(stderr, "Usage: %s input output\n", argv[0]);
    return 1;
  }

  // Open input & output files
  FILE *input = fopen(argv[1], "rb");
  if(input == NULL)
  {
    fprintf(stderr, "fopen: %s: %s\n", argv[1], strerror(errno));
    return 1;
  }

  gzFile output = gzopen(argv[2], "wb");
  if(output == NULL)
  {
    fprintf(stderr, "gzopen: %s: %s\n", argv[2], strerror(errno));
    fclose(input);
    return 1;
  }

  // Read in data from the input file, and compress & write it to the
  // output file
  char buffer[8192];
  int N;
  while((N = fread(buffer, 1, sizeof(buffer), input)) > 0)
  {
    gzwrite(output, buffer, N);
  }

  fclose(input);
  gzclose(output);

  return 0;
}

像这样使用它:

$ ./mygzip input output.gz
$ diff input <(gunzip < output.gz)  # Verify that it worked

【讨论】:

    【解决方案2】:

    您是否尝试过简单地使用 zlib?这里有一个教程: http://www.zlib.net/zlib_how.html

    当然,这是制作 gzip 文件的好方法。根据您的既定目标,我假设使用popen() 或system() 运行程序不是很好(需要机器安装其他东西,更不用说如果您要经常这样做,效率会降低)。

    【讨论】:

      【解决方案3】:

      在 shell 中有一个明确的方法可以做到这一点:

      gzip ball.tar
      

      您可以让 C++ 程序使用popen 系统调用来运行该命令。

      您还可以为 zlib 编写一个模拟 c++ iostream 的包装器(例如 http://www.cs.unc.edu/Research/compgeom/gzstream/)

      【讨论】:

        【解决方案4】:

        为tar 命令构造一个const char* 参数字符串并将其传递给cstdlib.h 中的system() 函数可能是最简单的方法。或者使用 popen(),正如 Foo Bah 的回答所提到的。我很难相信您的目标平台包括没有tar 或gzip 的平台,因为即使是像BusyBox 这样的恢复shell 也可以访问tar。一旦 system()/popen() 返回(显然检查返回码是否成功),为压缩文件创建一个 ifstream 并用它做任何你喜欢的事情。

        编辑:当您标记某些东西时,Linux 人们倾向于认为这意味着特定且仅指 Linux。当然tar 不适用于 Windows 操作系统的标准安装,所以在这种情况下,是的,提供捆绑的 zlib dll 并使用 zlib,就像 John 提到的那样。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-14
          • 2012-06-17
          • 2012-09-17
          • 1970-01-01
          • 2010-12-22
          • 2016-04-11
          • 2013-10-01
          相关资源
          最近更新 更多