使用boost::iostreams庫壓縮和解壓資料
今天專案中正好要用到gzip對資料進行壓縮,正好查到了boost::iostreams這個庫,因此查了相關資料,下面記錄下自己對這個庫的一些理解吧。
iostreams主要有兩類東西組成,一個是device,另一個是filter,可以到原始碼目錄下找,iostreams目錄下有這兩個目錄可以找到相關類。
device像是一種裝置,不能單獨使用,要配合普通流stream或stream_buffer來使用,可將流中的資料輸入/輸出到這個裝置上,可分為
Source,它以讀取的方式訪問字元序列,如:file_source 做檔案輸入。
Sink,它以寫的方式訪問字元序列,如:file_sink 做檔案輸出。
stream<file_source> 那麼這個就是一個檔案輸入流,類似於ifilestream,而stream<file_sink>就是一個檔案輸出流,類似於ofilestream。
filter像一種過濾器,和device一樣,也是不能單獨使用的,要配合過濾流filtering_stream或filtering_streambuf來使用,將流中的資料按一種規則過濾,可分為:
InputFilter,過濾通過Source讀取的輸入,如:gzip_decompressor 按gzip演算法解壓流中的資料。
OutputFilter,過濾向Sink寫入的輸出,如:gzip_compressor 按gzip演算法壓縮流中的資料
但filtering_stream是要維護一個filter的連結串列的,以device為結束。輸出過濾流filtering_ostream,是按順序執行filter,然後再輸出到devic上,如:
壓縮時
filtering_ostream out;
out.push(gzip_compressor());//gzip OutputFilter
out.push(bzip2_compressor());//bzip2 OutputFilter
out.push(boost::iostreams::file_sink("test.txt"));//以file_sink device結束
這就會將流的資料先按gzip壓縮,然後再按bzip2壓縮之後,才輸出到text.txt檔案中。
解壓時
filtering_istream in;
in.push(gzip_decompressor());/gzip InputFilter
in.push(bzip2_decompressor());/bzip2 InputFilter
in.push(file_source("test.txt"));
這時候先將test.txt檔案中資料讀出,然後按bzip2解壓,然後再按gzip解壓,存入in流中,正好是壓縮的逆序。
要使用zlib壓縮,首先需要通過boost編譯zlib。
1下載zlib(http://www.zlib.net/)
2,設定 zlib的路徑(進入 dos 介面)
set ZLIB_SOURCE=" E:/zlib-1.2.8"
3編譯
bjam --toolset=msvc-9.0 --with-iostreams --build-type=complete
注:zlib不需要提前編譯
附實現程式碼
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/device/file.hpp>
#include <iostream>
#include <sstream>
int main()
{
try{
std::stringstream ss_comp;
boost::iostreams::filtering_ostream out;
out.push(boost::iostreams::zlib_compressor());
//out.push(ss_comp); //壓縮到字元流中
out.push(boost::iostreams::file_sink("test.txt")); //壓縮到檔案中
boost::iostreams::copy(std::stringstream("hello"), out);
std::cout << "compressor data:" << ss_comp.str() << std::endl;
std::stringstream ss_decomp;
boost::iostreams::filtering_istream in;
in.push(boost::iostreams::zlib_decompressor());
//in.push(ss_comp); //從字元流中解壓
in.push(boost::iostreams::file_source("test.txt")); //從檔案中解壓
boost::iostreams::copy(in, ss_decomp);
std::cout << "decompressor data:" << ss_decomp.str() << std::endl;
}
catch(std::exception& e)
{
std::cout << "exception:" << e.what() << std::endl;
}
catch(...)
{
std::cout << "unknown exception." << std::endl;
}
system("pause");
return 0;
}