[zlib , C++] estrarre file .gz

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
andreafioraldi
Prode Principiante
Messaggi: 24
Iscrizione: martedì 12 febbraio 2013, 11:26
Desktop: KDE
Distribuzione: Slackware 14.1 x86_64
Località: Pontinia(LT)
Contatti:

[zlib , C++] estrarre file .gz

Messaggio da andreafioraldi »

Ciao a tutti,
ho la necessità di leggere e decomprimere un file gz e poi assegnare il contenuto decompresso a una stringa (buf).
attualmente sto usando questo codice , ma la stringa finale contiene un risultato parziale , non tutto il file gz viene decompresso.
(ad esempio se il file decompresso dovrebbere contenere la stringa "ciao a tutti" , buf contiene solo "ciao a")

Codice: Seleziona tutto

void Extract(string path,string dir )
{
string buf;
gzFile  file;
file = gzopen ( path.c_str() , "r");
if (! file) 
{
        cerr << "gzip error: " << path << ": " << strerror(errno) << "\n";
        exit(1);
}
while (1) {
        int err;                    
        int bytes_read;
        unsigned char buffer[LENGTH];
        bytes_read = gzread (file, buffer, LENGTH - 1);
        buffer[bytes_read] = '\0';
	buf += (char*)buffer;
	if (bytes_read < LENGTH - 1) 
	{
		if (gzeof (file)) {
			break;
		}
		else {
			const char * error_string;
			error_string = gzerror (file, & err);
			if (err) {
				cerr << "error: " << error_string << "\n";
				exit(1);
			}
		}
	}
}
gzclose (file);

Bfa P;
P.Set(buf);
P.Extract(dir);
}
qualcuno che è esperto con zlib sà come aiutarmi? grazie.
"Disobedience, in the eyes of anyone who has read history, is man's original virtue. It is through disobedience and rebellion that progress has been made."
-- Oscar Wilde, The Soul of Man Under Socialism
ixamit
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 499
Iscrizione: giovedì 14 novembre 2013, 10:16

Re: [zlib , C++] estrarre file .gz

Messaggio da ixamit »

Ci sono delle incongruenze nel tuo codice... forse hai copiato qualcosa di vecchio.
1) gzFile e' definito diversamente nella nuova zlib.

Codice: Seleziona tutto

 grep -m 1 gzFile /usr/include/zlib.h
 typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
[/s]EDIT: svista mia, non e' il tuo caso. Tanti errori sul web presenti sulla definizione

2) leggi l'header:
/usr/include/zlib.h ha scritto: /*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));

Opens a gzip (.gz) file for reading or writing. The mode parameter is as
in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
for fixed code compression as in "wb9F". (See the description of
deflateInit2 for more information about the strategy parameter.) 'T' will
request transparent writing or appending with no compression and not using
the gzip format.

"a" can be used instead of "w" to request that the gzip stream that will
be written be appended to the file. "+" will result in an error, since
reading and writing to the same gzip file is not supported. The addition of
"x" when writing will create the file exclusively, which fails if the file
already exists. On systems that support it, the addition of "e" when
reading or writing will set the flag to close the file on an execve() call.

These functions, as well as gzip, will read and decode a sequence of gzip
streams in a file. The append function of gzopen() can be used to create
such a file. (Also see gzflush() for another way to do this.) When
appending, gzopen does not test whether the file begins with a gzip stream,
nor does it look for the end of the gzip streams to begin appending. gzopen
will simply append a gzip stream to the existing file.

gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression. When
reading, this will be detected automatically by looking for the magic two-
byte gzip header.

gzopen returns NULL if the file could not be opened, if there was
insufficient memory to allocate the gzFile state, or if an invalid mode was
specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
errno can be checked to determine if the reason gzopen failed was that the
file could not be opened.
*/
Avatar utente
andreafioraldi
Prode Principiante
Messaggi: 24
Iscrizione: martedì 12 febbraio 2013, 11:26
Desktop: KDE
Distribuzione: Slackware 14.1 x86_64
Località: Pontinia(LT)
Contatti:

Re: [zlib , C++] estrarre file .gz

Messaggio da andreafioraldi »

Alla fine ho risolto usando z_stream e non gzFile.
se a qualcuno potrebbe essere utile posto la funzione in cui decomprimo una stringa:

Codice: Seleziona tutto

void Extract(string path)
{

string dir = vard + "/processing";
string fp = fileLoad(path);

z_stream S;
memset(&S, 0, sizeof(S));

if ( inflateInit2(&S, 16+MAX_WBITS) != Z_OK)
	cerr << "gzip error: " << strerror(errno) << "\n";

S.next_in = (unsigned char*)fp.data();
S.avail_in = fp.size();

char _read[32768];
string buf;
int RES;

do 
{
	S.next_out = (unsigned char*)_read;
	S.avail_out = sizeof(_read);

	RES = inflate(&S, 0);

	if (buf.size() < S.total_out) 
	{
		buf.append(_read,
		S.total_out - buf.size());
        }

} 
while (RES == Z_OK);

inflateEnd(&S);

if (RES != Z_STREAM_END) 
	cerr << "gzip error: " << RES << ": " << S.msg << "\n";

Bfa P;
P.Set(buf);
P.Extract(dir);

}
Ciao :-)
"Disobedience, in the eyes of anyone who has read history, is man's original virtue. It is through disobedience and rebellion that progress has been made."
-- Oscar Wilde, The Soul of Man Under Socialism
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 3 ospiti