¿Cómo leo / escribo archivos gzipeados en C ++?
-
05-07-2019 - |
Pregunta
¿Cómo leo / escribo archivos comprimidos con gzip en C ++?
El iostream
envuelve las clases aquí se ve bien, y aquí hay un ejemplo de uso simple:
gz::igzstream in(filename);
std::string line;
while(std::getline(in, line)){
std::cout << line << std::endl;
}
Pero no pude vincularlo realmente (aunque tengo un /usr/lib/libz.a
). Un simple
g++ test-gzstream.cpp -lz
no lo hizo ( referencia no definida a gz :: gzstreambase :: ~ gzstreambase ()
).
Solución
Obviamente necesita el archivo cpp donde también se define el destructor gzstreambase, es decir, gzstream.cpp (ese es el error del enlace). libz es solo un c-api para gzip, no sabe nada de c ++ stdlib streams.
La librería iostream de Boost también tiene secuencias gzip y bzip2.
EDITAR: se actualizó el enlace para apuntar a la última versión del código que incluye una corrección de error importante.
Otros consejos
Considera usar los filtros zip de Boost. Según ellos, admite el formato bzip
, gzip
y zlib
.
Para brindar más detalles de los que otros usuarios mencionaron brevemente, a continuación se explica cómo logré trabajar con gzstream
en mi computadora.
Primero, descargué gzstream
y lo instalé en mi casa (las dos últimas líneas se pueden agregar a su ~ / .bash_profile
):
cd ~/src
mkdir GZSTREAM
cd GZSTREAM/
wget http://www.cs.unc.edu/Research/compgeom/gzstream/gzstream.tgz
tar xzvf gzstream.tgz
cd gzstream
make
export CPLUS_INCLUDE_PATH=$HOME/src/GZSTREAM/gzstream
export LIBRARY_PATH=$HOME/src/GZSTREAM/gzstream
Luego, probé la instalación:
make test
...
# *** O.K. Test finished successfully. ***
Finalmente, escribí un programa ficticio para comprobar que pudiera usar la biblioteca de forma efectiva:
cd ~/temp
vim test.cpp
Aquí está el código (¡muy minimalista, debería ser mejorado mucho para aplicaciones reales!):
#include <iostream>
#include <string>
#include <gzstream.h>
using namespace std;
int main (int argc, char ** argv)
{
cout << "START" << endl;
igzstream in(argv[1]);
string line;
while (getline(in, line))
{
cout << line << endl;
}
cout << "END" << endl;
}
Así es como lo compilé:
gcc -Wall test.cpp -lstdc++ -lgzstream -lz
Y por último, pero no menos importante, aquí es cómo lo usé:
ls ~/ | gzip > input.gz
./a.out input.gz
START
bin/
src/
temp/
work/
END
También tuve este problema con el antiguo compilador GCC. Solo solucioné esto haciendo una versión de gzstream solo para el encabezado que debería ser más fácil de usar.
Esto es de la " Página de inicio de la biblioteca Gzstream "
O bien compile gzstream.C a mano, Colócalo en alguna biblioteca, y muévete. gzstream.h en la búsqueda de inclusión Ruta de tu compilador. O usa el proporcionado Makefile, adaptar su variables, y seguir los comentarios en el Makefile.