2010-08-08 8 views
2

J'utilise boost::iostreams::gzip_decompressor avec boost::iostreams::filterimg_streambuf pour lire les fichiers gzip.booster gzip lire des fichiers avec des ordures à la traîne

certains de mes fichiers ont ce zcat appelle trailing trash

% zcat somefile 
data 
data 
data 

gzip: somefile: decompression OK, trailing garbage ignored 

Ce que je veux pour gzip boost à se comporter de la même manière.

Lorsque vous essayez de décompresser le même fichier avec boost, en utilisant la fonction suivante, je reçois une exception gzip_error (de bad_header)

static int read_gzip(fs::path f, stringstream& s) 
{ 
     ifstream file(f.string().c_str(), ios_base::in | ios_base::binary); 
     io::filtering_streambuf<io::input> in; 

     in.push(io::gzip_decompressor()); 
     in.push(file); 

     try { 
      io::copy(in, s); 
      return 1; 
     } 
     catch (io::gzip_error& e) { 
      fprintf(stderr, "(read_gzip) io::copy exception %s %s (%d)\n", f.string().c_str(), e.what(), e.error()); 
     } 

     return 0; 
} 

quand il lance une exception, le stingstream reste vide.

comme solution de contournement, je peux lire l'octet de données par octet en utilisant quelque chose comme ceci:

static int read_gzip(fs::path f, string& s) 
{ 
     ifstream file(f.string().c_str(), ios_base::in | ios_base::binary); 
     io::filtering_streambuf<io::input> in; 
     char buf[1]; 

     in.push(io::gzip_decompressor()); 
     in.push(file); 

     try { 
      std::streamsize result; 
      while ((result = io::read(in, buf, 1)) != -1) { 
       s.append(buf, 1); 
      } 

      return 1; 
     } 
     catch (io::gzip_error& e) { 
      fprintf(stderr, "(read_gzip) io::copy exception %s %s (%d)\n", f.string().c_str(), e.what(), e.error()); 
     } 

     return 0; 
} 

mais il semble plutôt inefficace.

Quelle est la bonne façon de lire les fichiers gzippés avec des ordures à la traîne?

Merci.

Répondre

2

Ok, Ce qui a finalement fonctionné pour moi est d'utiliser zlib avec différents window_bits afin qu'il puisse décompresser gzip.

#include <zlib.h> # for MAX_WBITS 

static int read_gzip(fs::path f, stringstream& s) 
{ 
     ifstream file(f.string().c_str(), ios_base::in | ios_base::binary); 
     io::filtering_streambuf<io::input> in; 

     io::zlib_params p; 
     p.window_bits = 16 + MAX_WBITS; 

     in.push(io::zlib_decompressor(p)); 
     in.push(file); 

     try { 
      io::copy(in, s); 
      return 1; 
     } 
     catch (io::zlib_error & e) { 
      fprintf(stderr, "(read_gzip) io::copy exception %s :: %s (%d)", f.string().c_str(), e.what(), e.error()); 
     } 

    return 0; 
} 

décompresse les fichiers gzip réguliers et les fichiers gzip avec les ordures arrière sans jeter une exception.