2013-07-26 2 views
0

У меня есть пример файла gzip со стандартным заголовком gzip 1F 8B 08 00 ..., когда я надуваю его с помощью функций inflate* в zlib, выход составляет всего 11 байтов (на самом деле вывод должен быть около 4 Кбайт), но когда я распаковывать его с gz* функциями, она производит правильный вывод, код:Декомпрессия с функциями gz * успешно выполнена, но не выполнена с помощью функций inflate *, используя zlib

  1. с помощью gz* (это может произвести правильный вывод):

    #define CHUNK 10240 
    int gz_decompress(const char *path) { 
        gzFile f = gzopen(path, "rb"); 
        if(!f) 
         return -1; 
    
        unsigned char result[CHUNK]; 
        int bytes_read = gzread(f, result, CHUNK); 
        if(bytes_read < CHUNK) 
         if(!gzeof(f)) 
          return -2; 
        gzclose (f); 
        return 0; 
    } 
    
  2. использованием inflate* (выход составляет всего 11 байт):

    #define CHUNK 10240 
    int inf(FILE *source) 
    { 
        int ret; 
        unsigned have; 
        z_stream strm; 
        unsigned char in[CHUNK]; 
        unsigned char out[CHUNK]; 
    
        /* allocate inflate state */ 
        strm.zalloc = Z_NULL; 
        strm.zfree = Z_NULL; 
        strm.opaque = Z_NULL; 
        strm.avail_in = 0; 
        strm.next_in = Z_NULL; 
        // ret = inflateInit(&strm); 
        ret = inflateInit2(&strm, 16 + 15); 
        if (ret != Z_OK) 
         return ret; 
    
        /* decompress until deflate stream ends or end of file */ 
        do { 
         strm.avail_in = fread(in, 1, CHUNK, source); 
         if (strm.avail_in == 0) 
          break; 
         strm.next_in = in; 
    
         /* run inflate() on input until output buffer not full */ 
         do { 
          strm.avail_out = CHUNK; 
          strm.next_out = out; 
          ret = inflate(&strm, Z_NO_FLUSH); 
          assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 
          switch (ret) { 
          case Z_NEED_DICT: 
           ret = Z_DATA_ERROR;  /* and fall through */ 
          case Z_DATA_ERROR: 
          case Z_MEM_ERROR: 
           (void)inflateEnd(&strm); 
           return ret; 
          } 
          have = CHUNK - strm.avail_out; 
         } while (strm.avail_out == 0); 
    
         /* done when inflate() says it's done */ 
        } while (ret != Z_STREAM_END); 
    
        /* clean up and return */ 
        (void)inflateEnd(&strm); 
        return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 
    } 
    

В самом деле, второй фрагмент происходит от официального примера использования Zlib zpipe.c, я изменил только вызов inflateInit(&strm); к inflateInit2(&strm, 16 + 15); согласно this zlib gzip discussion, но теперь я понятия не имею, почему это не удается, кто-нибудь может помочь?

ответ

0

На ваш комментарий inf() возвращает Z_OK, что означает, что поток gzip успешно распаковывается и проверяется.

Что означает «вывод только 11 байтов»? Ваша функция inf() может вообще не производить вывод.

+0

Извините за ответ, поскольку последние два дня являются выходными, я открываю файл с опцией 'binary', а' inf() 'возвращает' Z_OK', значение которого равно 0, я отлаживаю внутри этой функции, там нет никакой ошибки. –

+0

Да, я согласен с тобой, он ничего не должен выводить, но на самом деле он выдал вывод с 11 байтами, каждый байт равен 0. Я вставил пример файла здесь: http://www.filehostfree.com/?d= 51F605CA1, действительно оцените, если бы у вас был тест на нем. –

+0

У меня нет времени для отладки кода. Вы можете подсчитать байты, сгенерированные в 'inf()' и/или записать их, чтобы проверить правильность декомпрессии. Ваши 11 байтов поступают откуда-то еще целиком, так как ваш 'inf()', как показано, не выводит результат. –

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