IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

[java.util.Zip] vérifier l'intégrité d'une archive


Sujet :

Collection et Stream Java

  1. #1
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut [java.util.Zip] vérifier l'intégrité d'une archive
    Bonjour,

    Tout est dans le titre, dans l'une de mes applications je zip des fichiers dans des archives (une archive par fichier, soit un fichier pour une archive). Or depuis un petit moment je constate que les fichiers produit par mon application donne des erreurs lors du dézippage de ces archives par le client :
    Je voulais donc savoir s'il est possible en Java de faire un CRC afin de controler l'intégrité de l'archive ?

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    je proposerais assez naivement d'utiliser l'api zip de java pour décompresser ce que tu viens de compresser, histoire de voir si t'as pas d'erreur.

  3. #3
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut
    Effectivement c'est la première chose que j'ai fait pour voir, malheureusement la décompression fonctionne bien alors que le fichier est corrompu. En gros, alors que les logiciels comme winZip, Unrar, etc affiche bien un message d'erreur CRC et demande s'il faut réellement décompresser l'archive en question.

    J'ai ensuite voulu afficher le CRC de l'archive (fonction getCrc() de l'API), et j'obtiens un -1. Je pense que ce CRC est à mettre soi-même lors de la compression suite à un contrôle CRC.

    Mon but est donc désormais de trouver une manière de faire pour reconnaitre cette erreur, et si elle a lieu, faire un petit algo pour supprimer mon archive et la compresser à nouveau.

    Pourquoi cela ? Parce que j'ai remarqué qu'en utilisant l'API Zip, j'ai aléatoirement cette erreur CRC qui apparait sur des archives, et donc je voudrais corrigé ce petit bug par une nouvelle compression de mes fichiers (pour le moment).

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    tu peux toujours comparer ce que tu décompresse, au fur et à mesure, avec les données de départ.

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    tu peux toujours comparer ce que tu décompresse, au fur et à mesure, avec les données de départ.
    Oui, mais comment faire s'il n'y a que le fichier zip et non les fichiers de départs (par exemple si l'on ne fait que décompresser) ? (enfin, même si dans ce cas ci, c'est de la compression)

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    tu as getCrc() et setCrc() sur ZipEntry, qui peux servir à consulter l'information. Tu as la classe crc32 du package zip qui permet de calculer un crc. Il n'y a plus qu'à comparer.

  7. #7
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut
    Re,

    Merci à tout deux pour vos participations
    Je n'avais pas vu vos deux post, mais effectivement je suis tombé sur la classe CRC32 du même package Zip.

    Pour éclaircir la situation :
    - c'est mon programme qui fait la compression des fichiers en archive, sans calculer de CRC pour le moment.
    - le problème de fichier corrompu arrive lorsque le client (ou nous même) décompressons les archives en question.

    Conclusion, ce que je vais faire :
    Lorsque je compresse mes fichiers, je vais calculer un CRC, puis tout de suite derrière je vais lire les fichiers de l'archive (sans pour antant les décompresser) juste afin de recalculer un CRC et pouvoir faire une comparaison avec celui généré lors de la compression.

    Je suis en train de le faire, ça me semble une méthode correcte mais je n'en suis pas certain, peut-être avez vous une idée ?

    Je vous remercie bien de votre aide en tout cas

  8. #8
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut
    Suite à ces indications, voici ce que j'ai fait.

    Deux méthodes, l'une pour compresser, l'autre pour décompresser, toute deux retournant un CRC (ces deux méthodes se trouvent dans une classe nommée 'TestZip' :
    compressSimpleFile(String,String)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
     
    	public CRC32 compressSimpleFile ( String theFile, String thePath ) throws DocdbException {
     
    		final int BUF_SIZE	= 2048;
    		byte[] data = new byte[BUF_SIZE];
    		CRC32 myCrc = new CRC32();
    		String myArcName = thePath.concat("archive.zip");
     
    		try{
    			FileOutputStream dest = new FileOutputStream(myArcName);
    			BufferedOutputStream buff = new BufferedOutputStream(dest);
    			ZipOutputStream out = new ZipOutputStream(buff);
    			out.setLevel(1);
     
     
    			FileInputStream fi = new FileInputStream(theFile);
    			BufferedInputStream buffi = new BufferedInputStream(fi);
    			ZipEntry entry = new ZipEntry(new File(theFile).getName());
    			out.putNextEntry(entry);
    			int count = 0;
    			while ( (count = buffi.read(data,0,BUF_SIZE)) != -1 ){
    				myCrc.update(data,0,count);
    				out.write(data,0,count);
    			}
    			entry.setCrc(myCrc.getValue());
    			out.closeEntry();
    			buffi.close();
    			out.close();
    		}catch(Exception e){
    			throw new DocdbException(e.getMessage());
    		}
     
    		return myCrc;
     
    	}
    unzipAndControlLastEntry(String)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
     
    	public CRC32 unzipAndControlLastEntry ( String theFile ) throws DocdbException {
     
    		final int BUF_SIZE	= 2048;
    		byte[] data = new byte[BUF_SIZE];
    		CRC32 myCrc = new CRC32();
     
    		try{
    			BufferedOutputStream dest = null;
    			FileInputStream fis = new FileInputStream(theFile);
    			BufferedInputStream buffi = new BufferedInputStream(fis);
    			ZipInputStream zis = new ZipInputStream(buffi);
     
    			ZipEntry entry;
    			FileOutputStream fos;
    			int count;
     
    			String outDir = theFile.substring(0,theFile.lastIndexOf(File.separator)+1);
     
    			while ( (entry = zis.getNextEntry()) != null ){
    				myCrc.reset();
    				fos = new FileOutputStream(outDir.concat(entry.getName()));
    				dest = new BufferedOutputStream(fos,BUF_SIZE);
    				while( (count = zis.read(data,0,BUF_SIZE)) != -1 ){
    					// --- Update the crc with data
    					myCrc.update(data);
    					dest.write(data,0,count);
    				}
    				dest.flush();
    				dest.close();
    			}
     
    			zis.close();
     
    		}catch(FileNotFoundException e){
    			System.err.println("FNFE");
    			throw new DocdbException(e.getMessage());
    		}catch(IOException e){
    			System.err.println("IOE");
    			throw new DocdbException(e.getMessage());
    		}
     
    		return myCrc;
     
    	}
    Voici un petit main pour les utiliser sur un fichier XML à compresser puis decompresser afin de comparer les valeurs des CRC à la fin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    public static void main (String[] args){
     
     
    		String thePath = "*****";
    		String theArchiveName = "archive.zip";
    		String theXmlFile = "*****.xml";
     
    		TestZip myZipManager = null;
    		CRC32 myCrcZip, myCrcRead;
    		try{
     
    			myZipManager = new TestZip();
    			myCrcZip = myZipManager.compressSimpleFile(theXmlFile,thePath);
    			myCrcRead = myZipManager.unzipAndControlLastEntry(thePath.concat(theArchiveName));
    			System.out.println("Comparison between two CRC :");
    			System.out.println("\tFist : "+myCrcZip.getValue());
    			System.out.println("\tSecd : "+myCrcRead.getValue());
     
    		}catch(DocdbException e){
    			System.err.println("ERROR : "+e.getMessage());
    		}
     
    	}
    Lorsque j'exécute ce programme plusieurs fois sur le même fichier XML en entrée, voici ce que ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Comparison between two CRC :
    	Fist : 3207811235
    	Secd : 2013059193
    On peut voir que les CRC ne sont pas les mêmes. On constate aussi que quelque soit le nombre de fois que l'on exécute le programme, les CRC sont toujours identiques.

    Ma question est donc : pourquoi les CRC ne sont pas égaux suite à la compression et la décompression de mon archive alors que la valeur d'initialisation est toujours la même (0) ?

    Remarque : si je l'exécute sur un autre fichier XML (pas les mêmes données donc), le résultat est similaire avec d'autres CRC :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Comparison between two CRC :
    	Fist : 394654411
    	Secd : 3549617088
    Je pense que ce n'est pas la bonne méthode à faire puisque ça ne fonctionne pas, dans ce cas quelle est la bonne méthode ^^ ?

  9. #9
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Ton CRC est différent car lors de la décompression tu le calcule mal car tu ne précise pas le nombre de caractère lu :
    Au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myCrc.update(data,0,count);


    Une question : les archives problématiques sont-elles générées sur le poste du client, ou est-ce qu'elles lui sont transmises par un moyen quelconque ?
    Il est possible que le zip soit corrompu pendant le "transport"...


    Sinon quelques remarques :
    • Utilises des try/finally pour fermer tes flux
    • Lorsque tu catch une exception pour en remonter une autre, c'est bien d'englober l'exception source (cela donne plus d'info lorsqu'on a un problème)


    a++

  10. #10
    kij
    kij est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Par défaut
    Effectivement il y a un transport via FTP derrière, mais j'ai déjà vérifié et les archives sont corrompues avant.
    Comment le savoir : suite à la compression j'ai une étape de validation des fichiers XML archivés, qui ouvre l'archive et valide une à une les entrées. Une erreur est parfois générée lors de cette étape à cause du CRC. Donc j'en déduis que c'est lors de la compression.

    Effectivement petite erreur d'inattention qui coûte cher :/ je vais modifier ça je te remercie.

    Pour ce qui est des try,catch et fermeture des flux, effectivement je vais modifier mon code également, le but étant juste de faire des tests ici.
    Je mettrais mon code plus propre lorsque j'aurai résolu ce problème.

    Pour ce qui est la gestion de la remontée de l'erreur, englober l'erreur source dans la seconde je ne vois pas trop ce que tu veux dire par là, j'avoue que niveau gestion des exceptions mes connaissances sont assez sommaire. Je vais voir un tutoriel la dessus.

    Merci encore pour ces bon(ne)s conseils/remarques

Discussions similaires

  1. Réponses: 1
    Dernier message: 06/06/2013, 09h29
  2. Vérifier l'intégrité d'une archive
    Par xxkirastarothxx dans le forum Langage
    Réponses: 2
    Dernier message: 16/09/2009, 12h29
  3. java.util.zip chemin des fichiers dans l'archive ZIP
    Par Bubu017 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 15/04/2008, 17h36
  4. Importer java.utils.zip ?
    Par Chii-san dans le forum Java ME
    Réponses: 3
    Dernier message: 15/03/2007, 15h01
  5. [C#] #ziplib ou J# (java.util.zip) pour ZIPper?
    Par SErhio dans le forum Windows Forms
    Réponses: 10
    Dernier message: 11/02/2005, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo