打开gzip文件以便在C中读取而不创建临时文件

Swi*_*tch 8 c file-io gzip

我有一些gzip文件,我想通过fopen和fscanf在C中读取.反正有没有将文件压缩到临时文件?

谢谢.

sha*_*tte 6

您可以使用libzlib直接打开gzip压缩文件.

它还提供了一个"gzopen"函数,其行为类似于fopen,但对gzip文件进行操作.但是,fscanf可能无法在这样的句柄上工作,因为它需要正常的FILE指针.


Gre*_*con 6

如果popen是公平的游戏,你可以做到这一点fopenfscanf:

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

int main(int argc, char *argv[])
{
  const char prefix[] = "zcat ";
  const char *arg;
  char *cmd;
  FILE *in;
  char buf[4096];

  if (argc != 2) {
    fprintf(stderr, "Usage: %s file\n", argv[0]);
    return 1;
  }

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

  sprintf(cmd, "%s%s", prefix, arg);

  in = popen(cmd, "r");
  if (!in) {
    fprintf(stderr, "%s: popen: %s\n", argv[0], strerror(errno));
    return 1;
  }

  while (fscanf(in, "%s", buf) == 1)
    printf("%s: got [%s]\n", argv[0], buf);

  if (ferror(in)) {
    fprintf(stderr, "%s: fread: %s\n", argv[0], strerror(errno));
    return 1;
  }
  else if (!feof(in)) {
    fprintf(stderr, "%s: %s: unconsumed input\n", argv[0], argv[1]);
    return 1;
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

例如:

$ zcat file.gz
Every good boy does fine.
$ ./gzread file.gz
./gzread: got [Every]
./gzread: got [good]
./gzread: got [boy]
./gzread: got [does]
./gzread: got [fine.]
Run Code Online (Sandbox Code Playgroud)


dzm*_*nto 5

不使用

sprintf(cmd, "zcat %s", argv[1]);
popen(cmd,"r");
Run Code Online (Sandbox Code Playgroud)

打开 .gz 文件。正确转义 argv[1] 。否则,您可能会遇到漏洞,尤其是当某些人注入参数 argv[1] 时,例如

123;rm -rf /
Run Code Online (Sandbox Code Playgroud)

把上面的指令改成已经有帮助了

sprintf(cmd, "zcat \'%s\'",argv[1]);
Run Code Online (Sandbox Code Playgroud)

您可能还想转义诸如 '\0'、'\''、'\;' 之类的字符 等等。