je vous expose mon problème, je recherche actuellement la façon de décompresser un dossier avec différents fichiers à l’intérieur. Le format de compression n'est pas un zip et ne peut être changé (fichier compressé = *.slog). J'ai écris un bout de code en pyhton qui le fait très bien :
#!/usr/bin/env python
import zipfile
import os
try:
os.mkdir("./test1")
except OSError:
pass
with zipfile.ZipFile("*.slog") as zip_ref:
zip_ref.extractall("test1")
Et je voudrais trouvé un équivalent en C++, j'ai en cherchant trouvé la librairie zlib mais qui (à moins d'une mauvais utilisation de ma part) ne marche pas sur les fichiers slog.
Quelqu'un aurait une idée ou une orientation vers laquelle je pourrais me pencher ?
Zip se fiche royalement du format du fichier, il prend des blocs et les compresse. Cela fonctionne avec tout type de contenu. En plus zipfile utilise très probablement zlib.
Bonjour, je reviens vers vous car je n'ai pas réussi à trouver. J'ai regardé différent code sur google ( en essayant de l'adapter) mais aucun n'a marché notamment celui sur le site officiel :
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <zlib.h>
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* avoid end-of-line conversions */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
/* do compression if no arguments */
/* if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
do decompression if -d specified */
//else if (argc == 2 && strcmp(argv[1], "-d") == 0) //{
FILE * source;
FILE * destination;
source = fopen("test.slog", "r");
destination = fopen("test.txt", "w");
ret = inf(source, destination);
if (ret != Z_OK)
zerr(ret);
return ret;
//}
/* otherwise, report usage */
/*else {
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
return 1;
}*/
}
je suis partie sur la base de l'exemple de zlib (en changeant le fichier) sauf que quand je l’exécute il m'affiche l'erreur suivante :
zpipe: invalid or incomplete deflate data
Donc si je comprend bien il a du mal avec le fichier slog ou avec le fait que le fichier source soit en slog et celui de destination soit en txt ?
Quelqu'un a une idée? Je pense que ça doit sauter aux yeux mais impossible de le voir
Oui effectivement je comprend qu'on vérifie SYSTÉMATIQUEMENT les valeurs de retour en C. Mais comme je l'ai dit plus haut le code n'est à 99% pas de moi puisque je l'ai pris de l'exemple sur ZLIB. Ce que je voulais faire c'est réussir à faire fonctionner ce code pour après pouvoir m'en inspirer et créer MON propre code.
Mais pour l'instant je n'arrive même pas à faire fonctionner l'exemple
Ton soucis vient du fait que zlib permet d'extraire des blocs zippés : donc tu as un flux d'octets, ça te le réduis ou décompresse en un autre flux d'octet.
Qu'est ce qu'un fichier zip ? Ce n'est pas que ça.
Un fichier zip, c'est une arborescence, un assemblage de fichiers, donc plusieurs blocs qui encodent la structure de l'arborescence, et dans cette arborescence, chaque fichier est un bloc zippé (qui lui peut etre "inflate").
Essaie de faire des recherches (par exemple) sur "minizip", c'est une lib qui s'appuie sur zlib et qui, il me semble, fait ce que tu veux.
Moi je l'avais recodé à la main pour le boulot le format zip, (qui s'appuie sur zlib) c'est pas infaisable...
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html