如何使用带有gzip压缩输入文件的boost :: iostreams :: mapped_file_source

时间:2015-04-11 04:14:43

标签: c++ boost gzip memory-mapped-files

我使用boost :: iostreams :: mapped_file_source从特定位置读取文本文件到特定位置并操纵每一行(使用g ++ -Wall -O3 -lboost_iostreams -o test main.cpp编译): / p>

#include <iostream>
#include <string>
#include <boost/iostreams/device/mapped_file.hpp>

int main() {
    boost::iostreams::mapped_file_source f_read;
    f_read.open("in.txt");

    long long int alignment_offset(0);

    // set the start point
    const char* pt_current(f_read.data() + alignment_offset);
    // set the end point
    const char* pt_last(f_read.data() + f_read.size());
    const char* pt_current_line_start(pt_current);

    std::string buffer;

    while (pt_current && (pt_current != pt_last)) {
        if ((pt_current = static_cast<const char*>(memchr(pt_current, '\n', pt_last - pt_current)))) {
            buffer.assign(pt_current_line_start, pt_current - pt_current_line_start + 1);
            // do something with buffer

            pt_current++;
            pt_current_line_start = pt_current;
        }
    }

    return 0;
}

目前,我想让这段代码处理gzip文件并修改代码如下:

#include<iostream>
#include<boost/iostreams/device/mapped_file.hpp>
#include<boost/iostreams/filter/gzip.hpp>
#include<boost/iostreams/filtering_streambuf.hpp>
#include<boost/iostreams/filtering_stream.hpp>
#include<boost/iostreams/stream.hpp>

int main() {
    boost::iostreams::stream<boost::iostreams::mapped_file_source> file;
    file.open(boost::iostreams::mapped_file_source("in.txt.gz"));

    boost::iostreams::filtering_streambuf< boost::iostreams::input > in; 
    in.push(boost::iostreams::gzip_decompressor());
    in.push(file);

    std::istream std_str(&in);
    std::string buffer;
    while(1) {
        std::getline(std_str, buffer);
        if (std_str.eof()) break;
        // do something with buffer
    }   
}   

这段代码也运行良好,但我不知道如何像第一段代码一样设置起点(pt_current)和终点(pt_last)。你能告诉我如何在第二个代码中设置这两个值吗?

1 个答案:

答案 0 :(得分:3)

答案是否定的,那是不可能的。压缩流需要有索引。


真正的问题是为什么?。您正在使用内存映射文件。进行即时压缩/解压缩只会降低性能并增加内存消耗。

如果您不是实际文件存储空间不足,那么您应该考虑二进制表示,或保持文本不变。

二进制表示可以回避使用随机访问的文本文件时所涉及的大部分复杂性。

一些鼓舞人心的样本:


您基本上发现的是文本文件不是随机访问,压缩使索引基本上模糊(没有从压缩流偏移到未压缩流偏移的精确映射)。

查看zlib FAQ中提到的zlib发行版中的zran.c示例:

  

28。 我可以在压缩流中随机访问数据吗?

     

不,没有一些准备。如果在定期压缩时使用Z_FULL_FLUSH,请在这些点上仔细写入所有待处理数据,并保留这些位置的索引,然后您可以在这些点开始解压缩。您必须小心不要经常使用Z_FULL_FLUSH,因为它会显着降低压缩率。或者,您可以扫描一次deflate流以生成索引,然后使用该索引进行随机访问。见examples/zran.c

¹你可以专门看看并行实现,例如pbzip2或pigz;这些必然会使用这些“块”或“框架”来安排跨核心的负载