Come faccio a leggere / scrivere file gzip in C ++?
-
05-07-2019 - |
Domanda
Come posso leggere / scrivere file compressi con gzip in C ++?
Le classi wrapper iostream
qui sembra buono, ed ecco un semplice esempio di utilizzo:
gz::igzstream in(filename);
std::string line;
while(std::getline(in, line)){
std::cout << line << std::endl;
}
Ma non sono stato in grado di collegarlo effettivamente (anche se ho un /usr/lib/libz.a
). Un semplice
g++ test-gzstream.cpp -lz
non lo ha fatto ( riferimento indefinito a gz :: gzstreambase :: ~ gzstreambase ()
).
Soluzione
Ovviamente è necessario il file cpp in cui è definito anche il distruttore gzstreambase, ovvero gzstream.cpp (questo è l'errore di collegamento). libz è solo un c-api per gzip, non sa nulla dei flussi c ++ stdlib.
La libreria iostream di Boost ha anche flussi gzip e bzip2.
EDIT: aggiornato il collegamento per puntare all'ultima versione del codice che include una correzione di bug importante.
Altri suggerimenti
Valuta l'utilizzo dei filtri zip Boost. Secondo loro, supporta il formato bzip
, gzip
e zlib
.
Per fornire maggiori dettagli rispetto a quanto è stato brevemente menzionato dagli altri utenti, ecco come sono riuscito a lavorare con gzstream
sul mio computer.
Innanzitutto, ho scaricato gzstream
e l'ho installato a casa mia (le ultime due righe possono essere aggiunte al tuo ~ / .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
Quindi, ho testato l'installazione:
make test
...
# *** O.K. Test finished successfully. ***
Alla fine, ho scritto un programma fittizio per verificare che potessi usare efficacemente la libreria:
cd ~/temp
vim test.cpp
Ecco il codice (molto minimalista, dovrebbe essere molto migliorato per le applicazioni reali!):
#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;
}
Ecco come l'ho compilato:
gcc -Wall test.cpp -lstdc++ -lgzstream -lz
E, ultimo ma non meno importante, ecco come l'ho usato:
ls ~/ | gzip > input.gz
./a.out input.gz
START
bin/
src/
temp/
work/
END
Ho avuto questo problema anche con il vecchio compilatore GCC. Ho appena risolto il problema creando un'intestazione solo nella versione di gzstream che dovrebbe essere più facile da usare.
Questo è tratto dalla " Home Page della libreria Gzstream "
Compilare gzstream.C manualmente, posizionalo in qualche libreria e spostalo gzstream.h nella ricerca include percorso del compilatore. Oppure usa il fornito Makefile, adattare il suo variabili e seguire le osservazioni in il Makefile.