zlibライブラリの使用

3514 ワード

1、zlib紹介
zlibは汎用的な圧縮ライブラリであり、メモリ内の圧縮と解凍関数を提供し、解凍されたデータの完全性を検出することができます.zlibはgzip(.gz)形式のファイルの読み書きもサポートします.
(1)データヘッダ
zlibは、gzipデータヘッダ、zlibデータヘッダ、またはデータヘッダを使用しないでデータを圧縮することができる.
通常、データ圧縮はzlibデータヘッダを使用します.これは、エラーデータ検出を提供するためです.データがデータヘッダを使用して書き込まれない場合、エラー検出のない元のDEFLATEデータになり、解凍ソフトウェアの呼び出し元は圧縮データがどこで終わるか分からない.
gzipデータヘッダはzlibデータヘッダよりも大きい.ファイル名や他のファイルシステム情報が保存されているため、実際には広く使用されているgzipファイルのデータヘッダフォーマットである.注意zlibライブラリ自体はgzipファイルを作成できませんが、圧縮データをgzipファイルヘッダのあるファイルに書き込むのは簡単です.
(2)アルゴリズム
現在、zlibは1つのLZ 77の変種アルゴリズム、DEFLATEのアルゴリズムしかサポートしていない.
このアルゴリズムは少ないシステムリソースを用いて,種々のデータに対して良好な圧縮効果を提供する.これもZIPファイルに例外なくこのアルゴリズムを用いている.(zipファイルフォーマットはいくつかの他のアルゴリズムをサポートしていますが).
zlibフォーマットは、データヘッダがこのような可能性があるにもかかわらず、他のアルゴリズムを拡張して使用されないように見えます.
2、zlib使用
一般的な関数:compressとuncompress.
(1)圧縮関数compress
int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
compress関数はsourceバッファの内容をdestバッファに圧縮します.sourceLenは、sourceバッファのサイズ(バイト)を表します.注意関数の2番目のパラメータdestLenはアドレス呼び出しです.関数を呼び出すと、destLenはdestバッファのサイズを表し、destLen>(sourceLen+12)*100.1%です.関数が終了すると、destLenは圧縮後のバッファの実際のサイズを表します.このときdestLen/sourceLenはちょうど圧縮率である.
compressが成功するとZ_を返すOK;十分なメモリがない場合はZ_を返しますMEM_ERROR;出力バッファが大きくなければZ_を返すBUF_ERROR.
(2)解凍関数uncompress
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
uncompress関数はsourceバッファの内容をdestバッファに解凍します.sourceLenは、sourceバッファのサイズ(バイト単位)です.
注意関数の2番目のパラメータdestLenはアドレス呼び出しです.関数が呼び出されると、destLenはdestバッファのサイズを表し、destバッファは解凍後のデータを収容するのに十分である.
解凍を行う場合は,圧縮されたデータがどの程度解凍されるかを事前に知る必要がある.これは、圧縮を行う前に、元のデータのサイズ(すなわち、解凍後のデータのサイズ)を保存することを要求する.これはzlib関数ライブラリの機能ではありません.追加の作業が必要です.関数が終了するとdestLenは解凍されたデータの実際のサイズである.
uncompressが成功するとZ_を返しますOK ;十分なメモリがない場合はZ_を返しますMEM_ERROR;出力バッファが大きくなければZ_を返すBUF_ERROR.入力データに誤りがあればZ_を返すDATA_ERROR.
(3)プログラムの例
圧縮解凍テストコード:
#include <cstring>
#include <cstdlib>
#include <iostream>
#include "zlib.h"
using namespace std;
int main()
{
    int err;
    Byte compr[200], uncompr[200];    // big enough
    uLong comprLen, uncomprLen;
    const char* hello = "12345678901234567890123456789012345678901234567890";
    uLong len = strlen(hello) + 1;
    comprLen = sizeof(compr) / sizeof(compr[0]);
    err = compress(compr, &comprLen, (const Bytef*)hello, len);
    if (err != Z_OK) {
        cerr << "compess error: " << err << '
'; exit(1); } cout << "orignal size: " << len << " , compressed size : " << comprLen << '
'; strcpy((char*)uncompr, "garbage"); err = uncompress(uncompr, &uncomprLen, compr, comprLen); if (err != Z_OK) { cerr << "uncompess error: " << err << '
'; exit(1); } cout << "orignal size: " << len << " , uncompressed size : " << uncomprLen << '
'; if (strcmp((char*)uncompr, hello)) { cerr << "BAD uncompress!!!
"; exit(1); } else { cout << "uncompress() succeed:
" << (char *)uncompr; } }

このプログラムをコンパイルして実行し、出力は
orignal size: 51 , compressed size : 22
orignal size: 51 , uncompressed size : 51
uncompress() succeed:
12345678901234567890123456789012345678901234567890
また、zlibはテストバンドコード:exampleを持参する.c.