Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Utilisation de zlib

4 réponses
Avatar
TSalm
Bonjour,

J'ai écrit une fonction qui lit un fichier zip et affiche la taille du
fichier décompressé.
Mais la taille ne correspond pas avec la taille du vrai fichier.

Je ne comprends pas d'où ça vient, je vous soumets donc mon code :

/* --------------- CODE -------------------- */

void displayContent( char* zFilePath )
{
const unsigned int buffSz = 2048;

unsigned int szRead;
char buffer[ buffSz ];
gzFile gzf = gzopen(zFilePath,"rb");

unsigned long szTotal = 0;

if ( gzf == NULL )
throw exception() ;

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead == 0 || szRead == (unsigned int) -1 )
break;

szTotal += szRead;

// for (unsigned int i=0;i<szRead;++i)
// putchar( buffer[i] ) ;
}

gzclose( gzf );

cout << "Size : " << szTotal << endl;

if ( szRead == (unsigned int) -1 )
throw exception();

}
/* ------------------------------------------------ */

ps: merci de ne pas vous formaliser sur le petit <<cout>>...

D'avance merci pour votre aide.
-TSalm

4 réponses

Avatar
Samuel Devulder
TSalm a écrit :
Bonjour,

J'ai écrit une fonction qui lit un fichier zip et affiche la taille du
fichier décompressé.
Mais la taille ne correspond pas avec la taille du vrai fichier.

Je ne comprends pas d'où ça vient, je vous soumets donc mon code :



C'est pas vraiment un pb de C, mais un pb d'api.

if ( gzf == NULL )
throw exception() ;



Hum pas très C ce throw...


while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead == 0 || szRead == (unsigned int) -1 )
break;



Et si gzread() retournait -2 ?

Je lis la doc:
Return Value

On success, gzread() shall return the number of bytes
decompressed into buf. If gzread() returns 0, either the
end-of-file has been reached or an underlying read error has
occurred. Applications should use gzerror() or gzeof() to
determine which occurred. On other errors, gzread() shall return
a value less than 0 and and applications may examine the cause
using gzerror().

En cas de pépin ca retourne un truc <0, et pas forcément -1.. Donc si ca
se trouve tu reçois un nombre négatif et tu le traite comme s'il était
positif avec toutes les catastrophes qui peut en découler.

De toute façon il ne faut pas jouer avec les unsigned sauf si on sait ce
qu'on fait très précisément. Bref, passe szRead à signed, fais un test
avec <=0, et tout devrait rentrer dans l'ordre je pense.

sam.
Avatar
TSalm
Le Sun, 06 Dec 2009 01:11:12 +0100, Samuel Devulder
a écrit:

TSalm a écrit :
Bonjour,
J'ai écrit une fonction qui lit un fichier zip et affiche la taille du
fichier décompressé.
Mais la taille ne correspond pas avec la taille du vrai fichier.
Je ne comprends pas d'où ça vient, je vous soumets donc mon code :



C'est pas vraiment un pb de C, mais un pb d'api.

if ( gzf == NULL )
throw exception() ;



Hum pas très C ce throw...



Oui. J'avoue que j'utilise certains mécanismes C++.

while (true)
{
szRead = gzread( gzf, buffer, buffSz );
if ( szRead == 0 || szRead == (unsigned int) -1 )
break;



Et si gzread() retournait -2 ?

Je lis la doc:
Return Value

On success, gzread() shall return the number of bytes
decompressed into buf. If gzread() returns 0, either the
end-of-file has been reached or an underlying read error has
occurred. Applications should use gzerror() or gzeof() to
determine which occurred. On other errors, gzread() shall return
a value less than 0 and and applications may examine the cause
using gzerror().

En cas de pépin ca retourne un truc <0, et pas forcément -1.. Donc si ca
se trouve tu reçois un nombre négatif et tu le traite comme s'il était
positif avec toutes les catastrophes qui peut en découler.



Merci. J'ai changé en unsigned int.
D'autant que mon buffer ne peut pas retourner une taille supérieure à
celle d'un signed int.

De toute façon il ne faut pas jouer avec les unsigned sauf si on sait ce
qu'on fait très précisément. Bref, passe szRead à signed, fais un test
avec <=0, et tout devrait rentrer dans l'ordre je pense.


En fait, ca ne me retourne même pas d'erreur.
Le problème vient en fait du format de mon fichier : la zlib ne gére pas
les fichiers zip.
Et si elle ne sait pas gérer le format compressé d'un fichier, il retourne
le fichier non décompressé :
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.

J'aurais préfèré qu'il me retourne une erreur...
en tout cas merci.
Avatar
-ed-
On 6 déc, 21:01, TSalm wrote:
>>   if ( gzf == NULL )
>>     throw exception() ;

> Hum pas très C ce throw...

Oui. J'avoue que j'utilise certains mécanismes C++.



Ce qui signifie que tu n'utilises pas un compilateur C, et donc que tu
t'es trompé de groupe. De toutes façons, tu a un problème de
bibliothèque applicative et non de langage. Je suggère de lire la doc
à fond (plusieurs fois) et d'expérimenter pas à pas.
Avatar
TSalm
>> >> if ( gzf == NULL )
>> throw exception() ;

> Hum pas très C ce throw...

Oui. J'avoue que j'utilise certains mécanismes C++.



Ce qui signifie que tu n'utilises pas un compilateur C, et donc que tu
t'es trompé de groupe.



Ca reste une bibliothèque C. De plus, j'utilise une syntaxe C. Ca aurait
très bien pu être un problème C je penses.

De toutes façons, tu a un problème de
bibliothèque applicative et non de langage. Je suggère de lire la doc
à fond (plusieurs fois) et d'expérimenter pas à pas.



Oui. Effectivement.
Mais la documentation n'est pas toujours complète. Pour preuve, il est
possible de vérifier que le fichier est bien dans un format lisible par la
zlib, mais cette fonction n'est pas documentée sur le site de la zlib.

Il s'agit de la fonction :

ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
Returns 1 if file is being read directly without decompression,
otherwise
zero.
*/

En espérant que ça puisse aider quelqu'un d'autre.

-TSalm