2010-01-20 2 views
4

Я использую zlib для выполнения сжатия gzip. zlib записывает данные непосредственно в открытый TCP-сокет после сжатия.Как определить сжатый размер из zlib для gzipped-данных?

/* 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); 

(конечно, все обработки ошибок удаляются)

Возникает вопрос: как определить, сколько байт были записаны в сокет? Все функции gz * в zlib имеют дело с байтами/смещениями в несжатом домене и говорят (искать) не работают для сокетов.

В заголовке zlib.h говорится: «Эта библиотека может дополнительно считывать и записывать потоки gzip в память». Запись в буфер будет работать (тогда я могу записать буфер в сокет впоследствии), но я не вижу, как это сделать с интерфейсом.

ответ

0

zlib может, по сути, записывать gzip-форматированные данные в буфер в памяти.

Эта запись zlib faq относится к комментариям в zlib.h. В файле заголовка в комментарии для deflateInit2() упоминается, что вы должны (произвольно?) Добавить 16 к 4-му параметру (windowBits), чтобы заставить библиотеку форматировать поток дефляции с помощью формата gzip (вместо значения по умолчанию «zlib» «формат»).

Этот код получает состояние Zlib настроен должным образом кодировать GZIP в буфер:

#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 интерфейс.

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.

+1

Не уверен, что я что-то упустил, но это, похоже, не генерирует форматированные данные gzip. – Andrew

Смежные вопросы