【问题标题】:how to use boost::iostreams::mapped_file_source with a gzipped input file如何将 boost::iostreams::mapped_file_source 与 gzip 输入文件一起使用
【发布时间】:2015-04-11 04:14:42
【问题描述】:

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

#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)。你能告诉我如何在第二个代码中设置这两个值吗?

【问题讨论】:

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


    【解决方案1】:

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


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

    如果您不缺少实际的文件存储,那么您可能应该考虑二进制表示,或者保持文本不变。

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

    一些鼓舞人心的样本:


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

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

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

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

    ¹您可以专门查看并行实现,例如pbzip2 或 pigz;这些将必然使用这些“块”或“帧”来安排跨内核的负载

    【讨论】:

    • 添加相关答案链接,激发你的想象力
    • 谢谢,你节省了我的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2011-09-19
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多