備忘録

備忘録

C++でzlibの圧縮と展開を行う方法

Ⅰ. はじめに

タイトルの通り「C++でzlibの圧縮と展開を行う方法」です。

Ⅱ. やり方

1. zlibをインストールする
vcpkg install zlib:x64-windows
2. サンプルプログラムを書く
#include <Windows.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <zlib.h>

constexpr auto BUFFER_SIZE = 0x4000;

// 展開する
std::string ZlibInflate(std::string &data)
{
  auto size = static_cast<unsigned int>(data.size());
  auto outBuf = new unsigned char[BUFFER_SIZE]();
  std::stringstream outStream;
  z_stream zStream{ 0 };
  auto ret = inflateInit(&zStream);

  zStream.avail_in = size;
  zStream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(data.data()));
  do
  {
    zStream.next_out = outBuf;
    zStream.avail_out = BUFFER_SIZE;
    ret = inflate(&zStream, Z_NO_FLUSH);
    auto outSize = BUFFER_SIZE - zStream.avail_out;
    outStream.write(reinterpret_cast<char *>(outBuf), outSize);
  } while (zStream.avail_out == 0);

  inflateEnd(&zStream);

  return outStream.str();
}

// 圧縮する
std::string ZlibDeflate(std::string &data, const int level)
{
  auto size = static_cast<unsigned int>(data.size());
  auto outBuf = new unsigned char[BUFFER_SIZE]();
  std::stringstream outStream;
  z_stream zStream{ 0 };
  auto ret = deflateInit(&zStream, level);

  zStream.avail_in = size;
  zStream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(data.data()));
  do
  {
    zStream.next_out = outBuf;
    zStream.avail_out = BUFFER_SIZE;
    ret = deflate(&zStream, Z_FINISH);
    auto outSize = BUFFER_SIZE - zStream.avail_out;
    outStream.write(reinterpret_cast<char*>(outBuf), outSize);
  } while (zStream.avail_out == 0);

  deflateEnd(&zStream);
  return outStream.str();
}

int main()
{
  auto rawData = std::string("hello world");
  // 圧縮する
  auto compressed = ZlibDeflate(rawData, Z_DEFAULT_COMPRESSION);
  // 展開する
  auto decompressed = ZlibInflate(compressed);

  std::cout << decompressed << std::endl;

  // debug
  // std::ofstream ofs("compressed", std::ios::binary);
  // ofs << compressed;
  // ofs.close();
}

実行結果

hello world