如何从压缩文件(gz)的字节流源获取可读文件描述符

时间:2015-04-17 10:04:31

标签: c io gz

我是C编程的新手。我使用的库需要来自字节流源的文件描述符。当我有常规文件时它工作得很好。但是,我输入了gz文件的通知。我需要解析的压缩数据总量约为5TB。我没有足够的空间来解压所有这些。

我使用了以下两种方法,但它们似乎无法正常工作,

input = gzopen (argv[i], "r");

第二种方法。

  arg = argv[1];
  cmd = malloc(sizeof(prefix) + strlen(arg) + 1);
  if (!cmd) {
       fprintf(stderr, "%s: malloc: %s\n", argv[i], strerror(errno));
        return 1;
    }
   sprintf(cmd, "%s%s", prefix, arg);
   input =  popen(cmd, "r");

如果可以提供任何帮助,我将不胜感激。

提前谢谢你。

1 个答案:

答案 0 :(得分:1)

我在这里推断一点,因为你没有向我们展示你正在使用的库函数的原型,但你在评论中说,当文件未压缩时,这适用于你:

fd = open(argv[i], O_RDONLY);

但使用gzopen()或popen()则不然。所以我收集到你正在使用的库函数采用文件描述符参数并读取和解释数据本身。

这会导致你的问题必然出现 - open()返回一个“int”文件描述符,但是gzopen()和popen()没有。

zlib文档以这种方式定义gzopen():

ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));

因此它返回一个自定义的'gzFile'文件描述符类型;你不能将它传递给计划执行read()的函数,期望一个int文件描述符。

同样,popen()返回一个stdio FILE *文件描述符,而不是int类,并将它传递给期望int的东西也不起作用。

因此,如果您想使用zlib,则必须使用自己的gzread()函数,然后通过int类型描述符(可能通过管道)将您读取的数据传递给库函数。这很麻烦。

您最好的选择可能是尝试使用popen(),但使用stdio fileno()函数获取作为FILE *基础的int描述符,并将其传递给库函数。

因此,假设原始代码中的'prefix'类似于“gzip -dc”,这是一个将解压缩数据从您的文件传输到stdout的命令,我们可以将您的代码修改为类似的东西(同样,您指定了arg)值'argv [1]'但在其他地方使用'argv [i]' - 我假设'1'是拼写错误的):

  char *prefix, *arg, *cmd;
  FILE *pinput;
  int fd;

  prefix = "gzip -dc ";
  arg = argv[i];
  cmd = malloc(strlen(prefix) + strlen(arg) + 1);
  if (!cmd) {
       fprintf(stderr, "%s: malloc: %s\n", argv[i], strerror(errno));
        return 1;
    }
   sprintf(cmd, "%s%s", prefix, arg);
   pinput =  popen(cmd, "r");
   fd = fileno(pinput);

然后你应该能够将'fd'传递给你的库函数,让它像未压缩的数据那样工作。

当你完成所有操作后别忘了释放(cmd)!