1. 程式人生 > >使用boost::iostreams庫壓縮和解壓資料

使用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_streamfiltering_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;
}