web-dev-qa-db-ja.com

zlibを使用してZipファイルを解凍します

2つの暗号化された「.txt」ファイルを含むarchive.Zipがあります。これらの2つのファイルを取得するために、アーカイブを解凍したいと思います。

これが私がこれまでにしたことです:

FILE *FileIn = fopen("./archive.Zip", "rb");
if (FileIn)
    printf("file opened\n");
else
    printf("unable to open file\n");

fseek(FileIn, 0, SEEK_END);
unsigned long FileInSize = ftell(FileIn);
printf("size of input compressed file : %u\n", FileInSize);

void *CompDataBuff = malloc(FileInSize);
void *UnCompDataBuff = NULL;

int fd = open ("archive.Zip", O_RDONLY);
CompDataBuff = mmap(NULL, FileInSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
printf("buffer read : %s\n", (char *)CompDataBuff);

uLongf UnCompSize = (FileInSize * 11/10 + 12);
UnCompDataBuff = malloc(UnCompSize);

int ret_uncp ;

ret_uncp = uncompress((Bytef*)UnCompDataBuff, &UnCompSize, (const Bytef*)CompDataBuff,FileInSize);
printf("size of uncompressed data : %u\n", UnCompSize);

if (ret_uncp == Z_OK){
    printf("uncompression ok\n");
    printf("uncompressed data : %s\n",(char *)UnCompDataBuff);
    }
if (ret_uncp == Z_MEM_ERROR)
    printf("uncompression memory error\n");
if (ret_uncp == Z_BUF_ERROR)
    printf("uncompression buffer error\n");
if (ret_uncp == Z_DATA_ERROR)
    printf("uncompression data error\n");

常に「解凍データエラー」が発生しますが、その理由はわかりません。次に、データを圧縮せずに2つのファイルを取得する方法を知りたいです。

8
user1336204

Zipは、ファイルとディレクトリのセットを表すために、圧縮されたデータストリームの周りにヘッダーとトレーラーの情報をラップするファイル形式です。圧縮されたデータストリームはほとんどの場合 データストリームのデフレート であり、実際にはzlibで生成およびデコードできます。 zlibは、Zipラッパー情報のcrc値を生成およびチェックするために使用できるcrc32関数も提供します。

Zlibが単独で実行しないのは、Zip構造をデコードおよび分解することです。 仕様 (それほど難しくはありません)を使用してそれを行うための独自のコードを作成するか、 contrib/minizipディレクトリ のminizipルーチンを使用することができます。 zlib配布 、Zipファイルを開いたり、アクセスしたり、閉じたりする機能を提供します。

17
Mark Adler

Zlibは、.Zipファイルを処理するためのライブラリではありません。 .Zipのような「アーカイブ」形式ではなく、データの単一ストリームのレベルで機能するzlibおよびgzipストリームの解凍をサポートします。

.Zipアーカイブを開いて操作するには、別のライブラリ(たとえば、 libzip ;他にもたくさんあります)が必要になります。

7
Kieron

前述のように、zlibは圧縮のみを処理し、アーカイブは行いません。あなたがしていることをZipまたはunzipしたいときは、たまたまZip形式のアーカイブからファイルを抽出することです(rar、7Zipなどの他の形式があります)

Zipまたはunzipファイルを作成する場合は、Zip形式を処理する必要があります。minizipは優れたライブラリであり、堅牢であり、かなり長い間存在しています。

Minizipの寄稿があります https://github.com/nmoinvaz/minizip それを使用する方法の例があります。それほど難しくはありません。minizip.cとminiunz.cで、使用方法のコードを確認できます。 (Minizipは圧縮にzlibを使用します)

また、ミニジップをラップし、それに多くの素敵な機能を追加して、使いやすく、よりオブジェクト指向にするライブラリを構築することになりました。フォルダ全体、ストリーム、ベクターなどを圧縮するだけでなく、すべてを完全にメモリ内で実行できます。

ここに例のあるリポジトリ: https://github.com/sebastiandev/zipper

ベータプレリリース: https://github.com/sebastiandev/zipper/releases/

コードは次のようになります。

Zipper zipper("ziptest.Zip");
zipper.add("somefile.txt");
zipper.add("myFolder");
zipper.close();
2
Sebastian