我写了一个代码来读取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);
}
}
我不知道如何知道这一点。或任何其他方法。