распаковать несколько файлов в один файл, используя boost

У меня есть набор сжатых файлов. Мне нужно распаковать все файлы и создать один большой файл. приведенный ниже код работает нормально, но я не хочу использовать std::stringstream, потому что файлы большие, и я не хочу создавать промежуточные копии содержимого файла.

Если я попытаюсь использовать boost::iostreams::copy(inbuf, tempfile); напрямую, он автоматически закроет файл (tmpfile). Есть ли лучший способ скопировать содержимое? или, по крайней мере, могу ли я избежать автоматического закрытия этого файла?

std::ofstream tempfile("/tmp/extmpfile", std::ios::binary);
for (set<std::string>::iterator it = files.begin(); it != files.end(); ++it)
{
    string filename(*it);
    std::ifstream gzfile(filename.c_str(), std::ios::binary);

    boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
    inbuf.push(boost::iostreams::gzip_decompressor());
    inbuf.push(gzfile);

    //closes tempfile automatically!!
    //boost::iostreams::copy(inbuf, tempfile); 

    std::stringstream out;
    boost::iostreams::copy(inbuf, out);
    tempfile << out.str();
}
tempfile.close();

person Dinesh Reddy    schedule 16.08.2016    source источник
comment
Использовать тривиальный выходной фильтр поверх целевого файла?   -  person n. 1.8e9-where's-my-share m.    schedule 16.08.2016


Ответы (1)


Я знаю, что есть способы сообщить Boost IOStreams, что он не должен закрывать потоки. Я полагаю, это требует, чтобы вы использовали boost::iostream::stream<> вместо std::ostream.

Мой простой обходной путь, который, кажется, работает, заключался в использовании временного std::ostream, связанного с одним объектом std::filebuf:

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <set>
#include <string>
#include <iostream>
#include <fstream>

int main() {
    std::filebuf tempfilebuf;
    tempfilebuf.open("/tmp/extmpfile", std::ios::binary|std::ios::out);

    std::set<std::string> files { "a.gz", "b.gz" };
    for (std::set<std::string>::iterator it = files.begin(); it != files.end(); ++it)
    {
        std::string filename(*it);
        std::ifstream gzfile(filename.c_str(), std::ios::binary);

        boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
        inbuf.push(boost::iostreams::gzip_decompressor());
        inbuf.push(gzfile);

        std::ostream tempfile(&tempfilebuf);
        boost::iostreams::copy(inbuf, tempfile); 
    }
    tempfilebuf.close();
}

Жить на Coliru

С примерными данными, такими как

echo a > a
echo b > b
gzip a b

Генерирует extmpfile, содержащий

a
b
person sehe    schedule 16.08.2016