c++ - 我如何在 c 中读取一个巨大的 .gz 文件(超过 5 gig 未压缩)

标签 c++ c 64-bit gzip

我有一些 .gz 压缩文件,未压缩时大约有 5-7gig。 这些是平面文件。

我写了一个程序,它接受一个未压缩的文件,并逐行读取它,效果很好。

现在我希望能够打开内存中的压缩文件并运行我的小程序。

我研究过 zlib,但找不到好的解决方案。

由于 32 位 unsigned int 的限制,使用 gzread(gzFile,void *,unsigned) 加载整个文件是不可能的。

我试过 gzgets,但与使用 gzread 读取相比,这几乎使执行时间加倍。(我在 2gig 样本上测试过。)

我还研究了“缓冲”,例如将 gzread 进程分成多个 2gig block ,使用 strcchr 找到最后一个换行符,然后设置 gzseek。 但是 gzseek 将模拟整个文件解压缩。这是非常慢的。

我没有看到任何理智的解决方案来解决这个问题。 我总是可以做一些检查,当前行是否真的有换行符(应该只出现在最后部分读取的行中),然后从程序中发生这种情况的地方读取更多数据。 但这可能会变得非常丑陋。

有什么建议吗?

谢谢

编辑: 我不需要一次拥有整个文件,一次只需要一行,但我有一台相当大的机器,所以如果那是最简单的,我就不会有问题。

对于所有建议通过管道传输 stdin 的人,与打开文件相比,我遇到了极度缓慢的情况。这是我几个月前制作的一个小代码片段,它说明了这一点。

time ./a.out 59846/59846.txt
#       59846/59846.txt
18255221

real    0m4.321s
user    0m2.884s
sys     0m1.424s
time ./a.out <59846/59846.txt
18255221

real    1m56.544s
user    1m55.043s
sys     0m1.512s

和源代码

#include <iostream>
#include <fstream>
#define LENS 10000

int main(int argc, char **argv){
  std::istream *pFile;

  if(argc==2)//ifargument supplied
    pFile = new std::ifstream(argv[1],std::ios::in);
  else //if we want to use stdin
    pFile = &std::cin;

  char line[LENS];
  if(argc==2) //if we are using a filename, print it.
    printf("#\t%s\n",argv[1]);

  if(!pFile){
    printf("Do you have permission to open file?\n");
    return 0;
  }

  int numRow=0;
  while(!pFile->eof()) {
    numRow++;
    pFile->getline(line,LENS);
  }
  if(argc==2)
    delete pFile;
  printf("%d\n",numRow);
  return 0;
}  

谢谢你的回复,我还在等金苹果

编辑2: 使用 cstyle FILE 指针而不是 c++ 流要快得多。所以我认为这是要走的路。

感谢您的参与

最佳答案

gzip -cd compressed.gz |你的程序

直接从未压缩的标准输入中逐行读取它。

编辑:回应您关于性能的评论。您是说与直接读取未压缩文件相比,逐行读取 STDIN 速度较慢。区别在于缓冲方面。通常,一旦输出可用(没有,或者那里的缓冲非常小),管道就会屈服于 STDIN。您可以从 STDIN 执行“缓冲 block 读取”并自己解析读取 block 以获得性能。

您也可以通过使用 gzread() 获得相同的结果,并可能获得更好的性能。 (读取一大块,解析 block ,读取下一个 block ,重复)

关于c++ - 我如何在 c 中读取一个巨大的 .gz 文件(超过 5 gig 未压缩),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1965751/

相关文章:

Android 应用 64 位支持截止日期推迟到 2020 年?

c++ - 64位Unix时间戳转换

c++ - 使用VTK绘制不同颜色的点

c++ - 将 Boost 累加器与 Eigen::Vector 类型一起使用

c++ - 有没有简单的方法来制作可折叠的 QWidget?

C - 我的代码在一个文件中有效,但在另一个文件中无效

计算C语言中2位数字的数量

delphi - 在Delphi XE6 x64下编译时GetProcAddress无法运行

c++ - 如何从 LPCTSTR 转换为 std::string?

c++ - 为什么 gcc 不为我决定内联或不内联这个功能?