Hello,
je tente d'écrire un bout de code qui utilise la zlib afin de compresser/décompresser des fichiers. Vu que je souhaite accéder à ces fichiers (de plusieurs Go) de manière aléatoire, j'ai choisi de découper le fichier à compresser en blocs (de 32ko, par exemple) puis de compresser chacun des blocs indépendament, en maintenant une table qui indique pour chaque bloc son offset dans le fichier, et sa taille compressée.
déjà, si il existe une meilleure méthode que celle que je me propose d'utiliser, j'y suis ouvert ;)
ensuite, mon problème est le suivant : la compression et la décompression se passent bien (de manière générale), mais pour certains blocs, la décompression échoue avec un Z_DATA_ERROR (-3) et le message que je récupère de la zlib est "invalid block type", ce qui voudrait dire que les données sont corrompues.
par contre, si dans la foulée je compresse puis décompresse ce bloc (sans passer par l'écriture sur le disque dur, donc), l'erreur n'apparaît pas...
le code et les données sont sur : http://boeglin.org/zlib/(...) , il y a en gros :
0.1/* : le code complet, qui devrait tourner sur des fichiers volumineux
badblock_uncomp et badblock_comp : un bloc de 32ko qui ne "passe" pas, décompressé et compressé
compress.c, uncompress.c : compresse et décompresse un seul bloc
test.c : compresse et décompresse sans passer par le disque
version : la version de mon paquet zlib
voilà, si quelqu'un a déjà vu celà, ou bien a quelques minutes à perdre, ca pourrait m'aider, vu que je n'ai pas l'impression d'avoir oublié quelque chose...
d'avance, merci ;)
P.S. : oui, j'ai bien lu la doc dans le zlib.h, et la faq de zlib...
P.P.S. : j'ai aussi fait une version utilisant directement deflate() et inflate() en Z_FULL_FLUSH et j'arrive au même résultat.
# pourquoi les blocs ?
Posté par aedrin . Évalué à 1.
mais, sinon, je ne saisis pas pourquoi tu utliises ce découpage en bloc... ou j'ai raté quelque chose.
tu dois accéder à un fichier de quelques Go de manière aléatoire ? c'est-à-dire ?
d'après ton test.c j'ai l'impression au final que l'intégralité de ton fichier (de plusieurs Go) est saucissonnée en blocs de 32 ko et que chacun de ces blocs est compressé, et tu te retrouves en une série de blocs de 32 ko compressés mis à la suite les uns des autres.
pourquoi tu ne compresse pas à la volée ton fichier (en lisant par blocs de 32ko si tu veux) et en écrivant directement dans un fichier compressé unique
je verrais bien un truc du style :
qu'est-ce que tu en penses ?
même principe pour la décompression, avec gzread et write cette fois-ci.
[^] # Re: pourquoi les blocs ?
Posté par aedrin . Évalué à 1.
il fallait lire
[^] # Re: pourquoi les blocs ?
Posté par Alexandre Boeglin . Évalué à 2.
en fait, la technique des 32ko est utilisée entre autres par le système de fichiers compressés squashfs.
# pas de solution mais une question
Posté par TheBreton . Évalué à 2.
// open files
fd_in = open("badblock_uncomp", O_RDONLY);
if(fd_in == -1)
exit(3);
fd_out = 1;
tu ne cree pas de fichier de sortie. Je suis pas un pro de linux mains le fd==1 ca ecris dans quoi ?
si c'est le stdout par exemple, ca ne voudrais pas dire que les caracteres speciaux comme 0x0a et 0x0d (voir meme inferieure a 0x20) pourrais etre intercepte par le recepeteur du flux et l'ecriture dans le fichier par un > pourrait en fait tronquer le resultat donc rendant la decompression impossible ?
je n'ai pas mon linux sous la main mais je me dis qu'en creeant un fichier de sortie au lieux d'utiliser fd_out=1 et en repassant ton block de donnée tu pourrais vite voir si c'est une piste de travail ?
[^] # Re: pas de solution mais une question
Posté par Alexandre Boeglin . Évalué à 1.
d'ailleurs :
int main(void){
unsigned short c;
for(c = 0; c <= 255; c++)
write(1, &c, 1);
return 0;
}
me donne bien :
[alex@dls zlib]$ ./a.out > pipo && wc pipo
1 1 256 pipo
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.