4

zlib を使用して gzip 圧縮を実行しています。zlib は、データを圧縮した後、開いている TCP ソケットにデータを直接書き込みます。

/* socket_fd is a file descriptor for an open TCP socket */
gzFile gzf = gzdopen(socket_fd, "wb");
int uncompressed_bytes_consumed = gzwrite(gzf, buffer, 1024);

(もちろん、すべてのエラー処理は削除されます)

問題は、ソケットに書き込まれたバイト数をどのように判断するかです。zlib のすべての gz* 関数は、圧縮されていないドメインのバイト カウント/オフセットを処理します。

zlib.h ヘッダーには、「このライブラリは、必要に応じてメモリ内の gzip ストリームを読み書きすることもできます」と記載されています。バッファへの書き込みは機能します (その後、バッファをソケットに書き込むことができます) が、インターフェイスでそれを行う方法がわかりません。

4

2 に答える 2

0

deflate*一連の呼び出しでこれを行うことができます。すべてを紹介するつもりはありませんが、このサンプルプログラム(ディレクトリで「test.c」という名前を付けました)は、開始するのに役立ちます。

#include <zlib.h>
#include <stdlib.h>
#include <stdio.h>

char InputBufferA[4096];
char OutputBufferA[4096];

int main(int argc, char *argv[])
{
    z_stream Stream;
    int InputSize;
    FILE *FileP;

    Stream.zalloc = malloc;
    Stream.zfree = free;
    /* initialize compression */
    deflateInit(&Stream, 3);
    FileP = fopen("test.c", "rb");
    InputSize = fread((void *) InputBufferA, 1, sizeof(InputBufferA), FileP);
    fclose(FileP);
    Stream.next_in = InputBufferA;
    Stream.avail_in = InputSize;
    Stream.next_out = OutputBufferA;
    Stream.avail_out = sizeof(OutputBufferA);
    deflate(&Stream, Z_SYNC_FLUSH);
    /* OutputBufferA is now filled in with the compressed data. */
    printf("%d bytes input compressed to %d bytes\n", Stream.total_in, Stream.total_out);
    exit(0);
}

からのdeflateドキュメントを参照してzlib.hください。

于 2010-01-20T18:30:29.547 に答える
0

実際、zlib は gzip 形式のデータをメモリ内のバッファに書き込むことができます。

このzlib faqエントリは、zlib.h のコメントに従います。ヘッダー ファイルの deflateInit2() のコメントには、ライブラリが (デフォルトの "zlib " フォーマット)。

このコードは、gzip をバッファーにエンコードするように適切に設定された zlib 状態を取得します。

#include <zlib.h>
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
int level = Z_DEFAULT_COMPRESSION;
int method = Z_DEFLATED;  /* mandatory */
int windowBits = 15 + 16; /* 15 is default as if deflateInit */
                          /* were used, add 16 to enable gzip format */
int memLevel = 8;         /* default */
int strategy = Z_DEFAULT_STRATEGY;
if(deflateInit2(&stream, level, method, windowBits, memLevel, strategy) != Z_OK)
{
    fprintf(stderr, "deflateInit failed\n");
    exit(EXIT_FAILURE);
}

/* now use the deflate function as usual to gzip compress */
/* from one buffer to another. */

この手順により、gzopen/gzwrite/gzclose インターフェイスとまったく同じバイナリ出力が得られることを確認しました。

于 2010-01-22T23:08:32.030 に答える