Я написал код для чтения simple-text / bz2-сжатых файлов.
Я использовал магические символы файла 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 ГБ
Если каким-то образом я смог выяснить 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);
}
}
Я не понимаю, как узнать это заранее. Или любой другой подход.
Задача ещё не решена.
Других решений пока нет …