介紹如何在 C++ 程式中使用 Boost 函式庫的 gzip filter 進行串流資料的壓縮與解壓縮。
安裝 Boost 函式庫
在 Ubuntu Linux 中可以直接使用 apt
安裝 Boost 函式庫。安裝時可以將整套 Boost 的所有元件一次裝好:
# 安裝所有 Boost 套件
sudo apt install libboost-all-dev
或是只裝我們需要的元件:
# 安裝 Boost 套件的 iostreams 元件
sudo apt install libboost-iostreams-dev
Gzip 壓縮
這是將資料以 gzip 壓縮之後,將串流轉送至 std::cout
的例子。
#include <fstream> #include <iostream> #include <boost/iostreams/filtering_streambuf.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/filter/gzip.hpp> int main() { // 將檔案以串流方式開啟 std::ifstream file("data.txt", std::ios_base::in | std::ios_base::binary); // 建立 Filter Chain boost::iostreams::filtering_streambuf<boost::iostreams::input> in; // 加入 Gzip 壓縮 filter in.push(boost::iostreams::gzip_compressor()); // 加入資料來源 in.push(file); // 將 in 串流導入 std::cout boost::iostreams::copy(in, std::cout); }
使用 g++
指令編譯程式:
# 編譯程式 g++ compress.cpp -o compress -lboost_iostreams
若要以 CMake 編譯,可以搭配以下這個 CMakeLists.txt
設定檔:
cmake_minimum_required(VERSION 3.8) # 設定專案名稱 project(Compress) # 尋找並引入 Boost 函式庫的指定元件 find_package(Boost 1.56 REQUIRED COMPONENTS iostreams) # 增加一個執行檔 add_executable(compress compress.cpp) # 定義執行檔連結方式 target_link_libraries(compress Boost::iostreams)
Gzip 串流壓縮
這是一個以 filtering_ostream
串流來進行 gzip 壓縮的範例,適用於大量資料的壓縮,其編譯方式跟上一個例子完全相同。
#include <iostream> #include <boost/iostreams/device/file.hpp> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filter/gzip.hpp> int main() { // 建立 Filter Chain boost::iostreams::filtering_ostream out; // 加入 Gzip 壓縮 filter out.push(boost::iostreams::gzip_compressor()); // 加入 File Sink out.push(boost::iostreams::file_sink("data.gz")); // 輸入資料 out << "Hello, Boost!"; // 關閉串流 boost::iostreams::close(out); return 0; }
Gzip 解壓縮
這是將 gzip 壓縮的資料解壓縮之後,將串流轉送至 std::cout
的例子。
#include <fstream> #include <iostream> #include <boost/iostreams/filtering_streambuf.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/filter/gzip.hpp> int main() { // 將檔案以串流方式開啟 std::ifstream file("data.gz", std::ios_base::in | std::ios_base::binary); // 建立 Filter Chain boost::iostreams::filtering_streambuf<boost::iostreams::input> in; // 加入 Gzip 解壓縮 filter in.push(boost::iostreams::gzip_decompressor()); // 加入資料來源 in.push(file); // 將 in 串流導入 std::cout boost::iostreams::copy(in, std::cout); }
使用 g++
指令編譯程式:
# 編譯程式 g++ uncompress.cpp -o uncompress -lboost_iostreams
若要以 CMake 編譯,可以搭配以下這個 CMakeLists.txt
設定檔:
cmake_minimum_required(VERSION 3.8) # 設定專案名稱 project(UnCompress) # 尋找並引入 Boost 函式庫的指定元件 find_package(Boost 1.56 REQUIRED COMPONENTS iostreams) # 增加一個執行檔 add_executable(uncompress uncompress.cpp) # 定義執行檔連結方式 target_link_libraries(uncompress Boost::iostreams)
Gzip 串流解壓縮
這是一個以 filtering_ostream
串流來進行 gzip 解壓縮的範例,適用於大量資料的解壓縮,其編譯方式也都相同。
#include <iostream> #include <boost/iostreams/device/file.hpp> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filter/gzip.hpp> int main() { // 原始壓縮資料 int size = 1024; char* memblock = new char [size]; // 建立 Filter Chain boost::iostreams::filtering_ostream out; // 加入 Gzip 解壓縮 filter out.push(boost::iostreams::gzip_decompressor()); // 加入 File Sink out.push(boost::iostreams::file_sink("data.txt")); // 輸入資料 out.write(memblock, size); // 關閉串流 boost::iostreams::close(out); delete[] memblock; return 0; }
Gzip 壓縮字串
這一個簡單的 Gzip
類別可以用來對字串進行壓縮與解壓縮。
#include <sstream> #include <boost/iostreams/filtering_streambuf.hpp> #include <boost/iostreams/copy.hpp> #include <boost/iostreams/filter/gzip.hpp> class Gzip { public: static std::string compress(const std::string& data) { namespace bio = boost::iostreams; std::stringstream compressed; std::stringstream origin(data); bio::filtering_streambuf<bio::input> out; out.push(bio::gzip_compressor(bio::gzip_params(bio::gzip::best_compression))); out.push(origin); bio::copy(out, compressed); return compressed.str(); } static std::string decompress(const std::string& data) { namespace bio = boost::iostreams; std::stringstream compressed(data); std::stringstream decompressed; bio::filtering_streambuf<bio::input> out; out.push(bio::gzip_decompressor()); out.push(compressed); bio::copy(out, decompressed); return decompressed.str(); } };
使用這個 Gzip
類別時,編譯也要加上 -lboost_iostreams
參數。