【C言語】ファイルをzip圧縮する方法

この記事では、C言語を使ってファイルをzip圧縮する方法について解説します。

初心者の方でも理解しやすいように、代表的なライブラリであるzlib、libzip、minizipの使い方を具体的なコード例とともに紹介します。

目次から探す

zip圧縮のためのライブラリ選定

C言語でファイルをzip圧縮するためには、適切なライブラリを選定することが重要です。

ここでは、代表的なzip圧縮ライブラリであるzlib、libzip、minizipについて紹介し、それぞれの特徴と選定基準について解説します。

zip圧縮ライブラリの紹介

C言語でzip圧縮を行うためには、以下の3つのライブラリがよく使用されます。

  1. zlib
  2. libzip
  3. minizip

これらのライブラリは、それぞれ異なる特徴を持っており、用途やプロジェクトの要件に応じて選定することが重要です。

zlib

zlibは、圧縮と解凍のための汎用ライブラリであり、広く使用されています。

zlibは、gzip形式の圧縮をサポートしており、シンプルで効率的なAPIを提供しています。

zlibは、C言語での圧縮処理を行う際のデファクトスタンダードとも言える存在です。

libzip

libzipは、zipファイルの読み書きを行うためのライブラリです。

libzipは、zipファイルの作成、追加、削除、更新などの操作をサポートしており、zipファイルの管理を簡単に行うことができます。

libzipは、C言語でのzipファイル操作を行う際に非常に便利なライブラリです。

minizip

minizipは、zlibをベースにしたzip圧縮ライブラリであり、zlibの機能を拡張してzipファイルの読み書きをサポートしています。

minizipは、zlibのシンプルさを保ちながら、zipファイルの操作を行うための追加機能を提供しています。

minizipは、zlibと同様に軽量で効率的なライブラリです。

各ライブラリの特徴と選定基準

それぞれのライブラリには異なる特徴があり、プロジェクトの要件に応じて適切なライブラリを選定することが重要です。

以下に、各ライブラリの特徴と選定基準を詳しく解説します。

zlibの特徴

  • 軽量で高速: zlibは非常に軽量で高速な圧縮ライブラリです。

メモリ使用量も少なく、パフォーマンスが求められるアプリケーションに適しています。

  • 広範なサポート: zlibは多くのプラットフォームでサポートされており、移植性が高いです。
  • シンプルなAPI: zlibのAPIはシンプルで使いやすく、初心者でも簡単に利用できます。
  • gzip形式のサポート: zlibはgzip形式の圧縮をサポートしており、ファイルの圧縮と解凍が容易です。

libzipの特徴

  • 豊富な機能: libzipはzipファイルの作成、追加、削除、更新などの操作をサポートしており、zipファイルの管理が容易です。
  • 高い柔軟性: libzipは多くのオプションを提供しており、細かい制御が可能です。
  • エラーハンドリング: libzipは詳細なエラーハンドリング機能を提供しており、エラーの原因を特定しやすいです。
  • ドキュメントの充実: libzipは公式ドキュメントが充実しており、学習コストが低いです。

minizipの特徴

  • zlibベース: minizipはzlibをベースにしており、zlibのシンプルさと軽量さを保ちながら、zipファイルの操作をサポートしています。
  • 軽量で効率的: minizipは軽量で効率的なライブラリであり、リソースの少ない環境でも動作します。
  • 簡単なインターフェース: minizipはシンプルなインターフェースを提供しており、初心者でも扱いやすいです。
  • 基本的な機能の提供: minizipは基本的なzipファイルの読み書き機能を提供しており、シンプルな用途に適しています。

以上の特徴を踏まえて、プロジェクトの要件に最も適したライブラリを選定することが重要です。

次のセクションでは、各ライブラリを使用した具体的な実装方法について解説します。

zlibを使ったzip圧縮の実装

zlibのインストールと設定

zlibは、データ圧縮ライブラリであり、C言語でのファイル圧縮に広く使用されています。

まずは、zlibのインストールと設定方法について説明します。

zlibのダウンロードとインストール

zlibは公式サイトからダウンロードできます。

以下の手順でインストールを行います。

Windowsの場合

  1. zlibの公式サイト(zlib.net)から最新のzlibのソースコードをダウンロードします。
  2. ダウンロードしたファイルを解凍し、適当なディレクトリに配置します。
  3. コマンドプロンプトを開き、解凍したディレクトリに移動します。
  4. 以下のコマンドを実行してビルドします。
nmake -f win32/Makefile.msc

macOSの場合

  1. ターミナルを開き、Homebrewを使用してzlibをインストールします。
brew install zlib

Linuxの場合

  1. ターミナルを開き、以下のコマンドを実行してzlibをインストールします。
sudo apt-get install zlib1g-dev

これでzlibがシステムにインストールされます。

プロジェクトへのzlibの追加方法

zlibをプロジェクトに追加するには、以下の手順を行います。

  1. プロジェクトのディレクトリに移動します。
  2. Makefileにzlibのライブラリをリンクする設定を追加します。

以下はその例です。

CC = gcc
CFLAGS = -Wall -I/usr/local/include
LDFLAGS = -L/usr/local/lib -lz
all: myprogram
myprogram: myprogram.o
	$(CC) $(CFLAGS) -o myprogram myprogram.o $(LDFLAGS)
myprogram.o: myprogram.c
	$(CC) $(CFLAGS) -c myprogram.c
clean:
	rm -f myprogram myprogram.o

基本的な使用方法

zlibを使用するためには、まずヘッダーファイルをインクルードします。

#include <zlib.h>

次に、zlibの初期化、ファイルの圧縮と解凍の手順を説明します。

zlibの初期化

zlibの初期化は特に必要ありませんが、圧縮や解凍の際に使用する構造体や関数を適切に設定する必要があります。

ファイルの圧縮と解凍

zlibを使用してファイルを圧縮するには、compress関数を使用します。

解凍するには、uncompress関数を使用します。

サンプルコード

以下に、ファイルを圧縮するコード例と圧縮ファイルを解凍するコード例を示します。

ファイルを圧縮するコード例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define CHUNK 16384
void compressFile(const char *source, const char *dest) {
    FILE *src = fopen(source, "rb");
    FILE *dst = fopen(dest, "wb");
    if (!src || !dst) {
        perror("File open error");
        return;
    }
    z_stream strm;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    deflateInit(&strm, Z_DEFAULT_COMPRESSION);
    int flush;
    do {
        strm.avail_in = fread(in, 1, CHUNK, src);
        if (ferror(src)) {
            deflateEnd(&strm);
            perror("File read error");
            return;
        }
        flush = feof(src) ? Z_FINISH : Z_NO_FLUSH;
        strm.next_in = in;
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            deflate(&strm, flush);
            fwrite(out, 1, CHUNK - strm.avail_out, dst);
        } while (strm.avail_out == 0);
    } while (flush != Z_FINISH);
    deflateEnd(&strm);
    fclose(src);
    fclose(dst);
}
int main() {
    compressFile("input.txt", "output.zip");
    return 0;
}

圧縮ファイルを解凍するコード例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define CHUNK 16384
void decompressFile(const char *source, const char *dest) {
    FILE *src = fopen(source, "rb");
    FILE *dst = fopen(dest, "wb");
    if (!src || !dst) {
        perror("File open error");
        return;
    }
    z_stream strm;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    inflateInit(&strm);
    int ret;
    do {
        strm.avail_in = fread(in, 1, CHUNK, src);
        if (ferror(src)) {
            inflateEnd(&strm);
            perror("File read error");
            return;
        }
        if (strm.avail_in == 0)
            break;
        strm.next_in = in;
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_NO_FLUSH);
            switch (ret) {
                case Z_NEED_DICT:
                case Z_DATA_ERROR:
                case Z_MEM_ERROR:
                    inflateEnd(&strm);
                    return;
            }
            fwrite(out, 1, CHUNK - strm.avail_out, dst);
        } while (strm.avail_out == 0);
    } while (ret != Z_STREAM_END);
    inflateEnd(&strm);
    fclose(src);
    fclose(dst);
}
int main() {
    decompressFile("output.zip", "output.txt");
    return 0;
}

これらのコード例を参考にして、zlibを使ったファイルの圧縮と解凍を実装することができます。

zlibは非常に強力で柔軟なライブラリであり、さまざまな用途に対応できます。

ぜひ活用してみてください。

libzipを使ったzip圧縮の実装

libzipのインストールと設定

libzipは、C言語でzipファイルを操作するためのライブラリです。

以下の手順でlibzipをインストールし、プロジェクトに設定します。

libzipのダウンロードとインストール

  1. 公式サイトからダウンロード:

libzipの公式サイト(https://libzip.org/)から最新のソースコードをダウンロードします。

  1. ソースコードの解凍:

ダウンロードしたアーカイブファイルを解凍します。

  1. ビルドとインストール:

解凍したディレクトリに移動し、以下のコマンドを実行してビルドとインストールを行います。

mkdir build cd build cmake .. make sudo make install

プロジェクトへのlibzipの追加方法

libzipをプロジェクトに追加するには、以下の手順を行います。

  1. ヘッダーファイルのインクルード:

ソースコードにlibzipのヘッダーファイルをインクルードします。

#include <zip.h>
  1. リンクオプションの追加:

コンパイル時にlibzipライブラリをリンクするために、以下のオプションを追加します。

-lzip

基本的な使用方法

libzipを使用するための基本的な手順を以下に示します。

libzipの初期化

libzipを使用する前に、ライブラリを初期化する必要があります。

以下のコードは、libzipの初期化方法を示しています。

#include <zip.h>
#include <stdio.h>
int main() {
	int err;
	zip_t *archive = zip_open("example.zip", ZIP_CREATE | ZIP_TRUNCATE, &err);
	if (archive == NULL) {
		char errbuf[1024];
		zip_error_to_str(errbuf, sizeof(errbuf), err, errno);
		fprintf(stderr, "Failed to open zip archive: %s\n", errbuf);
		return 1;
	}
	// ここにファイルの圧縮や解凍のコードを追加
	zip_close(archive);
	return 0;
}

ファイルの圧縮と解凍

libzipを使用してファイルを圧縮および解凍する方法を以下に示します。

サンプルコード

ファイルを圧縮するコード例

以下のコードは、テキストファイルをzipアーカイブに圧縮する例です。

#include <zip.h>
#include <stdio.h>
int main() {
    int err;
    zip_t *archive = zip_open("example.zip", ZIP_CREATE | ZIP_TRUNCATE, &err);
    if (archive == NULL) {
        char errbuf[1024];
        zip_error_to_str(errbuf, sizeof(errbuf), err, errno);
        fprintf(stderr, "Failed to open zip archive: %s\n", errbuf);
        return 1;
    }
    // 圧縮するファイルの内容
    const char *filename = "example.txt";
    const char *content = "This is a test file.";
    // 新しいファイルをzipアーカイブに追加
    zip_source_t *source = zip_source_buffer(archive, content, strlen(content), 0);
    if (source == NULL) {
        fprintf(stderr, "Failed to create zip source: %s\n", zip_strerror(archive));
        zip_close(archive);
        return 1;
    }
    if (zip_file_add(archive, filename, source, ZIP_FL_OVERWRITE) < 0) {
        fprintf(stderr, "Failed to add file to zip archive: %s\n", zip_strerror(archive));
        zip_source_free(source);
        zip_close(archive);
        return 1;
    }
    zip_close(archive);
    printf("File successfully compressed into example.zip\n");
    return 0;
}

圧縮ファイルを解凍するコード例

以下のコードは、zipアーカイブからファイルを解凍する例です。

#include <zip.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
    int err;
    zip_t *archive = zip_open("example.zip", 0, &err);
    if (archive == NULL) {
        char errbuf[1024];
        zip_error_to_str(errbuf, sizeof(errbuf), err, errno);
        fprintf(stderr, "Failed to open zip archive: %s\n", errbuf);
        return 1;
    }
    // 解凍するファイルの名前
    const char *filename = "example.txt";
    // ファイルをzipアーカイブから開く
    zip_file_t *file = zip_fopen(archive, filename, 0);
    if (file == NULL) {
        fprintf(stderr, "Failed to open file in zip archive: %s\n", zip_strerror(archive));
        zip_close(archive);
        return 1;
    }
    // ファイルの内容を読み取る
    char buffer[1024];
    zip_int64_t bytes_read = zip_fread(file, buffer, sizeof(buffer) - 1);
    if (bytes_read < 0) {
        fprintf(stderr, "Failed to read file in zip archive: %s\n", zip_file_strerror(file));
        zip_fclose(file);
        zip_close(archive);
        return 1;
    }
    // 読み取った内容を表示
    buffer[bytes_read] = '\0';
    printf("File content: %s\n", buffer);
    zip_fclose(file);
    zip_close(archive);
    return 0;
}

これで、libzipを使用してファイルを圧縮および解凍する方法が理解できたと思います。

次に、実際のプロジェクトでこれらのコードを活用してみてください。

minizipを使ったzip圧縮の実装

minizipのインストールと設定

minizipは、zlibの一部として提供される軽量なZIP圧縮ライブラリです。

まず、minizipを使用するためにはzlibをインストールする必要があります。

minizipのダウンロードとインストール

  1. zlibのダウンロード:

zlibの公式サイト(https://zlib.net/)から最新のzlibをダウンロードします。

  1. zlibのインストール:

ダウンロードしたzlibを解凍し、以下のコマンドを実行してインストールします。

./configure make sudo make install
  1. minizipの確認:

zlibのインストールが完了すると、minizipも一緒にインストールされます。

プロジェクトへのminizipの追加方法

プロジェクトにminizipを追加するには、zlibのヘッダーファイルとライブラリをインクルードする必要があります。

以下のように設定します。

#include <zlib.h>
#include <minizip/zip.h>
#include <minizip/unzip.h>

基本的な使用方法

minizipを使用してファイルを圧縮および解凍するための基本的な手順を以下に示します。

minizipの初期化

minizipを使用する前に、必要な初期化を行います。

以下のコードは、minizipの初期化方法を示しています。

zipFile zf;
zf = zipOpen("example.zip", APPEND_STATUS_CREATE);
if (zf == NULL) {
    printf("zipファイルの作成に失敗しました。\n");
    return -1;
}

ファイルの圧縮と解凍

ファイルの圧縮

ファイルを圧縮するには、以下の手順を実行します。

  1. ファイルを開く:

圧縮するファイルを開きます。

  1. ファイルをzipに追加:

開いたファイルをzipファイルに追加します。

  1. ファイルを閉じる:

zipファイルを閉じます。

FILE *fp = fopen("example.txt", "rb");
if (fp == NULL) {
    printf("ファイルのオープンに失敗しました。\n");
    return -1;
}
zip_fileinfo zi;
memset(&zi, 0, sizeof(zi));
zipOpenNewFileInZip(zf, "example.txt", &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
char buffer[4096];
int bytesRead;
while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
    zipWriteInFileInZip(zf, buffer, bytesRead);
}
fclose(fp);
zipCloseFileInZip(zf);
zipClose(zf, NULL);

圧縮ファイルの解凍

圧縮ファイルを解凍するには、以下の手順を実行します。

  1. zipファイルを開く:

解凍するzipファイルを開きます。

  1. ファイルを読み込む:

zipファイル内のファイルを読み込みます。

  1. ファイルを保存する:

読み込んだファイルを保存します。

unzFile uf = unzOpen("example.zip");
if (uf == NULL) {
    printf("zipファイルのオープンに失敗しました。\n");
    return -1;
}
if (unzGoToFirstFile(uf) != UNZ_OK) {
    printf("zipファイル内の最初のファイルに移動できませんでした。\n");
    unzClose(uf);
    return -1;
}
if (unzOpenCurrentFile(uf) != UNZ_OK) {
    printf("zipファイル内のファイルを開けませんでした。\n");
    unzClose(uf);
    return -1;
}
FILE *fp = fopen("extracted_example.txt", "wb");
if (fp == NULL) {
    printf("ファイルの作成に失敗しました。\n");
    unzCloseCurrentFile(uf);
    unzClose(uf);
    return -1;
}
char buffer[4096];
int bytesRead;
while ((bytesRead = unzReadCurrentFile(uf, buffer, sizeof(buffer))) > 0) {
    fwrite(buffer, 1, bytesRead, fp);
}
fclose(fp);
unzCloseCurrentFile(uf);
unzClose(uf);

サンプルコード

以下に、minizipを使用してファイルを圧縮および解凍する完全なサンプルコードを示します。

ファイルを圧縮するコード例

#include <stdio.h>
#include <zlib.h>
#include <minizip/zip.h>
int main() {
    zipFile zf = zipOpen("example.zip", APPEND_STATUS_CREATE);
    if (zf == NULL) {
        printf("zipファイルの作成に失敗しました。\n");
        return -1;
    }
    FILE *fp = fopen("example.txt", "rb");
    if (fp == NULL) {
        printf("ファイルのオープンに失敗しました。\n");
        return -1;
    }
    zip_fileinfo zi;
    memset(&zi, 0, sizeof(zi));
    zipOpenNewFileInZip(zf, "example.txt", &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
    char buffer[4096];
    int bytesRead;
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
        zipWriteInFileInZip(zf, buffer, bytesRead);
    }
    fclose(fp);
    zipCloseFileInZip(zf);
    zipClose(zf, NULL);
    printf("ファイルの圧縮が完了しました。\n");
    return 0;
}

圧縮ファイルを解凍するコード例

#include <stdio.h>
#include <zlib.h>
#include <minizip/unzip.h>
int main() {
    unzFile uf = unzOpen("example.zip");
    if (uf == NULL) {
        printf("zipファイルのオープンに失敗しました。\n");
        return -1;
    }
    if (unzGoToFirstFile(uf) != UNZ_OK) {
        printf("zipファイル内の最初のファイルに移動できませんでした。\n");
        unzClose(uf);
        return -1;
    }
    if (unzOpenCurrentFile(uf) != UNZ_OK) {
        printf("zipファイル内のファイルを開けませんでした。\n");
        unzClose(uf);
        return -1;
    }
    FILE *fp = fopen("extracted_example.txt", "wb");
    if (fp == NULL) {
        printf("ファイルの作成に失敗しました。\n");
        unzCloseCurrentFile(uf);
        unzClose(uf);
        return -1;
    }
    char buffer[4096];
    int bytesRead;
    while ((bytesRead = unzReadCurrentFile(uf, buffer, sizeof(buffer))) > 0) {
        fwrite(buffer, 1, bytesRead, fp);
    }
    fclose(fp);
    unzCloseCurrentFile(uf);
    unzClose(uf);
    printf("ファイルの解凍が完了しました。\n");
    return 0;
}

これで、minizipを使用してファイルを圧縮および解凍する方法についての基本的な理解が得られたと思います。

minizipは軽量で使いやすいライブラリであり、C言語でのZIP圧縮を簡単に実装することができます。

まとめ

各ライブラリの比較と選定ポイント

C言語でファイルをzip圧縮するためのライブラリには、zlib、libzip、minizipの3つが主にあります。

それぞれのライブラリには特徴があり、用途や要件に応じて選定することが重要です。

  • zlib: 汎用的で広く使われているライブラリ。

圧縮と解凍の基本機能を提供し、他のライブラリの基盤としても利用されることが多い。

  • libzip: zipファイルの操作に特化したライブラリ。

ファイルの追加、削除、更新などの操作が簡単に行える。

  • minizip: zlibの拡張として提供されるライブラリ。

軽量でシンプルなAPIを持ち、zlibと組み合わせて使うことが多い。

パフォーマンスの比較

パフォーマンスは、使用するライブラリや圧縮アルゴリズム、データの種類によって異なります。

一般的に、zlibは高速で効率的な圧縮を提供しますが、libzipやminizipも十分なパフォーマンスを発揮します。

  • zlib: 高速で効率的な圧縮・解凍が可能。

多くのプロジェクトで採用されている。

  • libzip: zipファイルの操作に特化しているため、ファイルの追加や削除などの操作が高速。
  • minizip: zlibを基盤としているため、zlibと同等のパフォーマンスを提供。

使いやすさの比較

使いやすさは、APIの設計やドキュメントの充実度によって異なります。

以下に各ライブラリの使いやすさを比較します。

  • zlib: 基本的な圧縮・解凍機能を提供するが、zipファイルの操作には追加の実装が必要。
  • libzip: zipファイルの操作に特化しており、直感的なAPIを提供。

ドキュメントも充実している。

  • minizip: zlibの拡張として提供されるため、zlibに慣れている場合は使いやすい。

実装時の注意点

ライブラリを使用する際には、以下の点に注意する必要があります。

  • 依存関係: 各ライブラリが依存する他のライブラリやツールのインストールが必要。
  • バージョン管理: 使用するライブラリのバージョンによってAPIが異なる場合があるため、バージョン管理が重要。
  • プラットフォーム依存性: 一部のライブラリは特定のプラットフォームでのみ動作する場合がある。

エラーハンドリング

エラーハンドリングは、安定したプログラムを作成するために重要です。

各ライブラリはエラーハンドリングのための機能を提供しています。

  • zlib: エラーコードを返す関数が多く、エラー処理がしやすい。
  • libzip: エラーオブジェクトを使用して詳細なエラー情報を取得可能。
  • minizip: zlibと同様にエラーコードを返すため、エラー処理が簡単。

メモリ管理

メモリ管理は、特に大規模なデータを扱う場合に重要です。

各ライブラリはメモリ管理のための機能を提供しています。

  • zlib: メモリ管理はユーザーに委ねられている部分が多い。
  • libzip: メモリ管理が比較的簡単で、メモリリークを防ぐための機能も提供。
  • minizip: zlibと同様に、メモリ管理はユーザーに委ねられている。

以上が、C言語でファイルをzip圧縮する方法です。

各ライブラリの特徴や選定ポイント、実装時の注意点を理解し、適切なライブラリを選んで効率的なプログラムを作成してください。

目次から探す