如何将 boost::iostreams::mapped_file_source 与 gzip 压缩的输入文件一起使用

use*_*776 5 c++ boost gzip memory-mapped-files

我用来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;
}
Run Code Online (Sandbox Code Playgroud)

目前,我想让这段代码也处理 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
    }   
}   
Run Code Online (Sandbox Code Playgroud)

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

seh*_*ehe 3

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

\n\n
\n\n

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

\n\n

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

\n\n

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

\n\n

一些鼓舞人心的例子:

\n\n\n\n
\n\n

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

\n\n

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

\n\n
\n

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

\n\n

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

\n
\n\n

\xc2\xb9 您可以专门查看并行实现,例如 pbzip2 或 pigz;这些必须使用这些“块”或“帧”来调度跨核心的负载

\n