尝试将gzip中的文件提取到C ++中的临时文件夹

时间:2018-07-27 07:49:50

标签: c++ boost gzip

我想使用c ++提取gzip中的文件。我正在使用Boost库。这是我的代码:

//Read from the first command line argument, assume it's gzipped    
std::ifstream file(filepath, std::ios_base::in | std::ios_base::binary);
boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
inbuf.push(boost::iostreams::gzip_decompressor());
inbuf.push(file);
boost::iostreams::copy(inbuf, cout);

//Cleanup
file.close();

此代码将所有数据写入终端。但是,我想将所有文件分别提取到某个文件夹中。

1 个答案:

答案 0 :(得分:1)

我想说的就是按照你说的做:

#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
#include <fstream>

int main(int argc, char** argv) {
    auto dir = boost::filesystem::temp_directory_path() / "demo";
    boost::filesystem::create_directories(dir);

    for (boost::filesystem::path p : boost::make_iterator_range(argv+1, argv+argc)) {
        std::ifstream file(p.c_str(), std::ios_base::in | std::ios_base::binary);
        boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
        inbuf.push(boost::iostreams::gzip_decompressor());
        inbuf.push(file);

        auto output = dir / p.filename();
        std::cout << "Writing " << output << "\n";
        std::ofstream ofs(output.c_str(), std::ios::binary);
        boost::iostreams::copy(inbuf, ofs);
    }
}

因此,要使用像./test test.cpp.gz这样的参数来运行,会将解压缩后的输出写入临时目录中sasme名称的文件中:

$ ../build/sotest test.cpp.gz 
Writing "/tmp/demo/test.cpp.gz"

如何获取原始文件名?

我之前在另一个答案中对此进行了展示:How to get gzip_params from boost's gzip_decompressor()

所以你会得到这个:

#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
#include <fstream>

namespace fs = boost::filesystem;
using gz_t = boost::iostreams::gzip_decompressor;

int main(int argc, char** argv) {
    auto dir = fs::temp_directory_path() / "demo";
    create_directories(dir);

    for (fs::path p : boost::make_iterator_range(argv+1, argv+argc)) {
        std::ifstream file(p.c_str(), std::ios_base::in | std::ios_base::binary);
        boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
        inbuf.push(gz_t());
        inbuf.push(file);

        if (gz_t* gz = inbuf.component<0, gz_t>()) {
            auto output = dir / fs::unique_path(basename(p));
            {
                std::cout << "Writing " << output << "\n";
                std::ofstream ofs(output.c_str(), std::ios::binary);
                boost::iostreams::copy(inbuf, ofs);
            }

            std::cout << "Original filename: " << gz->file_name() << "\n";
            std::cout << "Original mtime: " << gz->mtime() << "\n";
            std::cout << "Zip comment: " << gz->comment() << "\n";
            if (!gz->file_name().empty()) {
                fs::rename(output, dir / fs::path(gz->file_name()).filename());
            }
        }

    }
}

现在,如果您像这样运行它

$ gzip -k test.cpp
$ mv test.cpp. gz renamed.gz

$ ../build/sotest renamed.gz 
Writing "/tmp/demo/renamed"
Original filename: test.cpp
Original mtime: 1532692097
Zip comment: 

$ find /tmp/demo/
/tmp/demo/
/tmp/demo/test.cpp