2012-02-02 12 views
10

Implementé la descompresión de archivos gzip/zlib como se muestra en sus ejemplos en el sitio de impulso.impulsar gzip descomprimir byte array

void CompressionUtils::Inflate(std::ifstream& inputFile, 
           std::ofstream& outputFile) 
{ 
    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::gzip_decompressor()); 
    in.push(inputFile); 
    boost::iostreams::copy(in, outputFile); 
} 

esto funciona bien. También estoy leyendo datos de un socket que obtengo de un servicio JSON en reposo que también está comprimido. Pensé que escribiría una implementación basada en memoria, qué difícil podría ser eso. Bueno, descubrí que no entiendo las transmisiones y los buffers de transmisión como debería. Culpo a los últimos años en Java;) .. Así que comencé por este camino.

void CompressionUtils::Inflate(char* compressed, 
           int size, 
           char* decompressed) 
{ 

    boost::iostreams::stream<boost::iostreams::array_source> source(compressed,size); 
    //std::stringstream str; 

    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::gzip_decompressor()); 
    in.push(source); 
    //boost::iostreams::copy(in, str); 
} 

pero estoy en una pérdida en cuanto a qué tipo de corriente que puede utilizar para obtener básicamente el descomprimido char* representación de la corriente descomprimido. Esto debería ser fácil, y probablemente lo sea, pero he estado perdiendo el último par de intentos infructuosos.

Respuesta

6

Obviamente, se encontró con filtering streams and stream buffers. Puede usar el mismo método al revés para obtener datos en una cadena.

no tengo mis propios ejemplos a mano, por lo que considero que esto sea un tanto pseudo-código, pero esto debe ser lo que usted está buscando:

namespace io = boost::iostreams; //<-- good practice 
typedef std::vector<char> buffer_t; 

void CompressionUtils::Inflate(const buffer_t &compressed, 
           buffer_t &decompressed) 
{ 
    io::filtering_ostream os; 

    os.push(io::gzip_decompressor()); 
    os.push(io::back_inserter(decompressed)); 

    io::write(os, &compressed[0], compressed.size()); 
} 

lo que puede utilizar la unidad de inserción posterior proporcionada por Aumentar.

Básicamente, lo que hace el código anterior es definir un flujo de salida en el que puede escribir. Está configurado para que todo el contenido escrito en él primero se descomprima por gzip y y luego anexado al back_inserter que, como back_inserters, se insertará en la parte posterior del buffer decompressed.

Además, como puede ver, los buffers están envueltos en std::vector. Hazme saber si esto funciona para ti.

+0

Muchas gracias por su respuesta. Voy a darle una oportunidad –