如何在C中按顺序解析gzip压缩的文本文件而不首先完全解压缩它

时间:2016-01-29 18:47:32

标签: c parsing file-io gzip sequential

我有相当大的文本文件(~1Gb),包含我想要解析的顺序数据(即从上到下读取的行)。这些文本文件以gzip格式压缩。

目前,我对解析这些文件的基本实现(我是zlib的新手,并且已经用C语言编写多年)是:

  1. 使用zlib库解压缩文件并将其写入磁盘(!)
  2. 从磁盘(!)读取解压缩的文本文件并逐行解析
  3. 希望,只要我了解如何通过以下方式更好地使用zlib(提示赞赏;-)),就可以改进这一点:

    1. 使用zlib库解压缩文件并将内容保留在内存中
    2. 读取文件(从内存中)并逐行解析
    3. 但是,我认为这可以进一步优化,以便解析文件" online"在解压缩的同时。我相信gzip解压缩有点顺序,所以有可能读取gzip文件,一旦解压缩了一行文本,就把它发送给解析器?这样可以避免两次扫描文件,并且可能还避免将解压缩的文件保留在内存中。

      以这种方式执行此操作answer that says it is possible and preferable。你能否告诉我如何实现(或使用实现的lib)这样的程序?

      谢谢,

      TEPP。

2 个答案:

答案 0 :(得分:3)

是。您甚至不必使用popen()来执行此操作; zlib包含一组完成此操作的函数:

#include <zlib.h>

gzFile fh = gzopen("file.gz", "rb");

char buf[1024];
char *line;
while ((line = gzgets(fh, buf, sizeof(buf)) != NULL) {
    // process line
}

gzclose(fh);

同一界面也支持一次写一行gzip文件;有关详细信息,请参阅文档。

答案 1 :(得分:0)

您可以通过popen打开一个gzip压缩文件,并按顺序从流中读取,就好像它是未压缩的一样,除非您无法进入流中。

以下是一些代码:

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

int main(int argc, char **argv) {
    char buffer[4096];
    char *cmd;
    int cmdsize;
    FILE *fp;
    int found = 0;

    if (argc < 3) {
        printf("usage: zgrep string file\n");
        return 2;
    }
    cmdsize = strlen("gunzip < ") + strlen(argv[2]) + 1;
    cmd = malloc(cmdsize);
    snprintf(cmd, cmdsize, "gunzip < %s", argv[2]);
    if ((fp = popen(cmd, "r")) == NULL) {
        perror("cannot run gunzip");
        return 1;
    }
    while (fgets(buffer, sizeof buffer, fp)) {
        if (strstr(buffer, argv[1])) {
            fputs(buffer, stdout);
            found = 1;
        }
    }
    fclose(fp);
    return found;
}