2016-08-16 2 views
1

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

Если я попытаюсь напрямую использовать 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(); 
+0

Использовать тривиальный выходной фильтр поверх целевого файла? –

ответ

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(); 
} 

Live On Coliru

С образцами данных, как

echo a > a 
echo b > b 
gzip a b 

Gen extmpfile, содержащий

a 
b 
Смежные вопросы