C++: Iterating lines in a GZ file using boost::iostreams
Problem:
You’ve got a gzipped file that you want to decompress using C++. You don’t want to use pipes to gzip in an external process. You don’t want to use zlib and manual buffering either.
Solution
This is an extension of the official gzip_decompressor example. It is also applicable to bzip2 files, assuming you use the correct decompressor filter.
The program takes a single command line argument (which is a gzipped file) and prints its decompressed output to stdout.
/**
* myzcat.cpp
* A zcat replacement, for educational purpose.
* Uses boost::iostream and zlib.
*
* Compile like this:
* clang++ -o myzcat myzcat.cpp -lz -lboost_iostreams
*
* This code is published as public domain.
*/
#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
int main(int argc, char** argv) {
if(argc < 2) {
std::cerr << "Usage: " << argv[0] << " <gzipped input file>" << std::endl;
}
//Read from the first command line argument, assume it's gzipped
std::ifstream file(argv[1], 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);
//Convert streambuf to istream
std::istream instream(&inbuf);
//Iterate lines
std::string line;
while(std::getline(instream, line)) {
std::cout << line << std::endl;
}
//Cleanup
file.close();
}