我有一些.gz压缩文件,大约5-7gig未压缩。 这些是平面文件。
我编写了一个程序,它接受一个未压缩的文件,并且每行读取一行,这非常有效。
现在我希望能够在内存中打开压缩文件并运行我的小程序。
我已经研究过zlib,但我找不到一个好的解决方案。
使用gzread(gzFile,void *,unsigned)加载整个文件是不可能的,因为32位无符号int限制。
我尝试了gzgets,但这几乎使执行时间加倍,而不是使用gzread读取。(我在2gig样本上测试过。)
我也研究过“缓冲”,例如将gzread进程拆分为多个2gig块,使用strcchr找到最后一个换行符,然后设置gzseek。 但gzseek将模拟一个完整的文件解压缩。这很慢。
我没有看到任何理智的解决方案。 我总是可以做一些检查,无论当前行是否实际上有一个换行符(应该只出现在最后一个部分读取的行中),然后从程序中发生这种情况的点读取更多数据。 但这可能会非常难看。
无论如何有任何建议吗?
感谢
编辑: 我不需要立刻拥有整个文件,一次只需要一行,但我有一台相当庞大的机器,所以如果这是最简单的我没有问题。
对于那些建议管道标准输入的人来说,与打开文件相比,我经历了极端的减速。这是我几个月前制作的一个小代码片段,它说明了这一点。
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;
}
感谢您的回复,我还在等待金苹果
EDIT2: 使用cstyle FILE指针而不是c ++流要快得多。所以我认为这是要走的路。
感谢您的所有输入
答案 0 :(得分:5)
gzip -cd compressed.gz | yourprogram
然后继续从stdin逐行读取它,因为它是未压缩的。
编辑:回应您对性能的评论。你说直接读取STDIN比直接读取未压缩文件要慢。不同之处在于缓冲。通常,只要输出可用,管道就会产生STDIN(没有或非常小的缓冲)。您可以从STDIN执行“缓冲块读取”并自行解析读取块以获得性能。
通过使用gzread()
,您可以获得相同的结果并获得更好的性能。 (读取一大块,解析块,读取下一个块,重复)
答案 1 :(得分:5)
gzread只读取文件的块,就像使用普通的read()调用一样循环播放。
您需要将整个文件读入内存吗?
如果你需要的是读取行,你可以将一个相当大的块(比如8192个字节)gzread()放入缓冲区,遍历该缓冲区并找到所有'\ n'个字符并将它们作为单独的行处理。你必须保存最后一块,只有一行的一部分,并将其添加到你下次读到的数据中。
你也可以从stdin中读取并调用你的应用程序,如
zcat bigfile.gz | ./yourprogram
在这种情况下,你可以在stdin上使用fgets和类似的东西。这也是有益的,因为你在一个处理器上运行解压缩并在另一个处理器上处理数据: - )
答案 2 :(得分:0)
我不知道这是否可以回答你的问题,但我认为这不仅仅是一个评论:
几个月前,我发现维基百科的内容可以像StackOverflow数据转储一样下载。两者都解压缩为XML。
我遇到了如何解析多GB压缩转储文件的描述。实际上,它是由Perl脚本完成的,但与您相关的部分是使用了Bzip2压缩。
Bzip2是一种块压缩方案,压缩文件可以拆分为可管理的部分,每个部分单独解压缩。
不幸的是,我没有链接与您分享,我不能建议您如何搜索它,除非说它是在维基百科的“数据转储”或“博客”页面上描述的。
编辑:实际上,我做有一个link