通过检测是否压缩读取simple / bz2-compressed-file(逐行)(文件大小很大)

时间:2018-03-08 20:59:16

标签: c++ stream compression boost-iostreams bz2

我写了一个代码来读取simple-text / bz2-compressed-file。 我使用bz2文件的魔术字符来检测文件是否被压缩

  

注意"用户可能会也可能不会提供具有适当扩展名的文件"

我的代码

#include <iostream>
#include <sstream>
#include <vector>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/bzip2.hpp>

// compile using
// g++ -std=c++11 code.cpp -lboost_iostreams
// run using
// ./a.out < compressed_file
// ./a.out < simple_file
// cat file_name | ./a.out

std::string BZ2 = ".bzip2";
std::string NO_EXT = "";

void uncompress(std::vector<char> & line, const std::string & file_ext){
    std::string str(line.begin(), line.end());
    std::cout << "size of line is " << str.length() <<std::endl;

    std::stringstream input(str);
    std::stringstream decompressed;
    boost::iostreams::filtering_istream in;

    if (file_ext == NO_EXT) {return;}
    if (file_ext == BZ2) {
        in.push(boost::iostreams::bzip2_decompressor());
        in.push(input);
        boost::iostreams::copy(in, decompressed);
        decompressed >> str;
        line.clear();
        std::copy(str.begin(),str.end(),std::back_inserter(line));
    }
}

std::vector<char>&readline(std::istream & stream, std::vector<char> & container) {
    char c;
    container.clear();
    while (stream && stream.get(c)) {
        container.push_back(c);
        if (c == '\n') break;
    }
    return container;
}

std::string get_ext(const std::vector<char> &line) { // working fine
    std::vector<std::pair<std::vector<char>, std::string>> types = { { {66, 90, 104}, BZ2} };// magic char of bzip file
    for (auto & type : types) if (std::equal(type.first.begin(), type.first.end(), line.begin())) return type.second;
    return NO_EXT;
}

void print_line(std::vector<char> &line) { //working fine
    std::string str(line.begin(), line.end());
    std::cout << str << std::endl;
}

int main () {
    std::vector<char> line;
    readline(std::cin, line);
    std::string file_ext = get_ext(line); //obitain the file extension

    uncompress(line, file_ext);
    print_line(line);

    while (readline(std::cin, line).size() != 0) {
        uncompress(line, file_ext);
        print_line(line);
    }
}

此代码存在问题。 在阅读压缩文件时。它正在读取整个压缩文件。 我不想将整个文件加载到内存中以测试file_type。

  

文件大小可能大于4 GB

     

如果通过某种方式我可以找出file_type,那么我这样做很容易。

std::string BZ2 = ".bzip2";
std::string NO_EXT = "";

void uncompress(std::istream & input,
                const std::string & file_ext,
                boost::iostreams::filtering_istream & in)
{
    if (file_ext == BZ2) {
        in.push(boost::iostreams::bzip2_decompressor());
    }
    in.push(input);
}

std::vector<char>&readline(boost::iostreams::filtering_istream & stream, std::vector<char> & container) {
    char c;
    container.clear();
    while (stream && stream.get(c)) {
        container.push_back(c);
        if (c == '\n') break;
    }
    return container;
}

std::string get_ext(const std::vector<char> &line) { // working fine
    std::vector<std::pair<std::vector<char>, std::string>> types = { { { 66, 90, 104 }, BZ2 } };

    for (auto & type : types) if (std::equal(type.first.begin(), type.first.end(), line.begin())) return type.second;

    return NO_EXT;
}

void print_line(std::vector<char> &line) { //working fine
    std::string str(line.begin(), line.end());
    std::cout << str << std::endl;
}

int main () {
    std::vector<char> line;
    boost::iostreams::filtering_istream in;
    std::string file_ext = BZ2; // suppose I already knew that beforehand

    uncompress(std::cin, file_ext, in);

    while (readline(in, line).size() != 0) {
        print_line(line);
    }
}

我不知道如何知道这一点。或任何其他方法。

0 个答案:

没有答案