Categories: C/C++

Boost 函式庫 Gzip Filter 串流壓縮教學與範例

介紹如何在 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 參數。

除了 gzip 之外,boost 也支援 zlibbzip2 的 filter。

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago