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

Entrée/Sortie Java Discussion :

[ZIP] Remplacer un fichier dans un Zip


Sujet :

Entrée/Sortie Java

  1. #1
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut [ZIP] Remplacer un fichier dans un Zip
    Bonjour à tous,

    Voici mon problème.
    J'ai un fichier zip tot.zip dans le quel se trouve 2000 fichiers. Il y a un fichier en particulier tata.txt que j'aimerai dézipper, modifier et remettre dans mon zip avec les modifications apportées.
    Dézipper tata.txt => OK
    Modifier tata.txt => OK
    Remettre tata.txt dans toto.zip en remplaçant l'ancien tata.txt => NOT OK.

    Est ce que quelqu'un à déjà eu et résolu ce pb ?
    Bien sur j'aimerais faire cela sans avoir à dézipper tout mon fichier toto.zip, mais est ce possible ?

    Pour l'instant j'utilise le code suivant mais celui ci me renvoie une erreur lorsqu'il veut ajouter un fichier qui existe déjà dans le zip. Peut être que ce que je veux faire n'est pas possible...

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    	public void addFilesToExistingZip(File zipFile,
    			String file, boolean fullPath) throws IOException {
    		// get a temp file
    		File tempFile = File.createTempFile(zipFile.getName(), null);
    		// delete it, otherwise you cannot rename your existing zip to it.
    		tempFile.delete();
     
    		boolean renameOk=zipFile.renameTo(tempFile);
    		if (!renameOk)
    		{
    			throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
    		}
    		byte[] buf = new byte[1024];
     
    		ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
    		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
     
    		ZipEntry entry = zin.getNextEntry();
    		while (entry != null) {
    			String name = entry.getName();
    			boolean notInFiles = true;
     
    			if (file.equals(name)) {
    				notInFiles = false;
    				break;
    			}
     
    			if (notInFiles) {
    				// Add ZIP entry to output stream.
    				out.putNextEntry(new ZipEntry(name));
    				// Transfer bytes from the ZIP file to the output file
    				int len;
    				while ((len = zin.read(buf)) > 0) {
    					out.write(buf, 0, len);
    				}
    			}
    			entry = zin.getNextEntry();
    		}
    		// Close the streams		
    		zin.close();
    		// Compress the file
     
    		InputStream in = new FileInputStream(file);
    		// Add ZIP entry to output stream.
    		if (fullPath) {
    			out.putNextEntry(new ZipEntry(file));
    		} else {
    			out.putNextEntry(new ZipEntry(new File(file).getName()));
    		}
     
    		// Transfer bytes from the file to the ZIP file
    		int len;
    		while ((len = in.read(buf)) > 0) {
    			out.write(buf, 0, len);
    		}
    		// Complete the entry
    		out.closeEntry();
    		in.close();
     
    		// Complete the ZIP file
    		out.close();
    		tempFile.delete();
    	}
    Merci de votre aide.
    N'hésitez pas à me questionner si cela n'est pas clair.

  2. #2
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Non, ce n'est pas possible, et ce n'est pas possible quelque soit le type de fichier.

    Pour faire ce genre de chose il faut une base de données, ou un fichier séquentiel indexé.

  3. #3
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut
    Bonjour gifffftane,

    Merci de ta réponse.
    Néanmoins en m'inspirant du code que j'ai posté dans mon premier post, j'ai réussi à faire ce que je voulais.
    En gros j'ai copié en premier dans un nouveau zip le fichier que j'ai modifié (tata.txt) , puis j'ai recopié le contenu de l'ancien zip (sauf tata.txt) dans le nouveau zip. Je ne suis pas sur qu'en terme de performance ce soit le top car dans mon code je lis 2 fois le toto.zip d'entrée mais bon... Ça fait ce que je veux.
    D'ailleurs si quelqu'un aurait une idée pour l'optimiser je suis preneur.

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    public void addFilesToExistingZip(File zipFile,
    			String file, boolean fullPath) throws IOException {
    		// get a temp file
    		File tempFile = File.createTempFile(zipFile.getName(), null);
    		// delete it, otherwise you cannot rename your existing zip to it.
    		tempFile.delete();
    		ArrayList name = new ArrayList();
     
    		boolean renameOk=zipFile.renameTo(tempFile);
    		if (!renameOk)
    		{
    			throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
    		}
    		byte[] buf = new byte[1024];
     
    		ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
    		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
     
    		ZipEntry entry = zin.getNextEntry();
     
    		while (entry != null) {
    			name.add(entry.getName());
    			entry = zin.getNextEntry();
    		}	
    		zin.close();
     
    		ZipInputStream zin2 = new ZipInputStream(new FileInputStream(tempFile));
    		if (fullPath) {
    			name.remove(file);
    			InputStream in = new FileInputStream(file);
    			// Add ZIP entry to output stream.
    			out.putNextEntry(new ZipEntry(file));
    			// Transfer bytes from the file to the ZIP file
    			int len;
    			while ((len = in.read(buf)) > 0) {
    				out.write(buf, 0, len);
    			}
    			// Add ZIP entry to output stream.
    			entry = zin2.getNextEntry();
    			while (entry != null) {
    				if (name.contains(entry.getName())) {
    					out.putNextEntry(new ZipEntry(entry.getName()));
    					// Transfer bytes from the ZIP file to the output file
    					int lent;
    					while ((lent = zin2.read(buf)) > 0) {
    						out.write(buf, 0, lent);
    					}
    				}
    				entry = zin2.getNextEntry();
    			}	
    			// Close the streams		
    			zin2.close();
    			// Complete the entry
    			out.closeEntry();
    			in.close();
     
    		} else {
    			name.remove(new File(file).getName());
    			InputStream in = new FileInputStream(file);
    			// Add ZIP entry to output stream.
    			out.putNextEntry(new ZipEntry(new File(file).getName()));
    			// Transfer bytes from the file to the ZIP file
    			int len;
    			while ((len = in.read(buf)) > 0) {
    				out.write(buf, 0, len);
    			}
    			// Add ZIP entry to output stream.
    			entry=zin2.getNextEntry();
    			while (entry != null) {
    				if (name.contains(entry.getName())) {
    					out.putNextEntry(new ZipEntry(entry.getName()));
    					// Transfer bytes from the ZIP file to the output file
    					int lent;
    					while ((lent = zin2.read(buf)) > 0) {
    						out.write(buf, 0, lent);
    					}
    				}
    				entry = zin2.getNextEntry();
    			}	
     
     
    			// Close the streams		
    			zin2.close();
    			// Complete the entry
    			out.closeEntry();
    			in.close();
    		}
     
    //		Complete the ZIP file
    		out.close();
    		tempFile.delete();
    	}
    Merci pour votre aide.

  4. #4
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Hoegaarden Voir le message
    En gros j'ai copié en premier dans un nouveau zip le fichier que j'ai modifié (tata.txt) , puis j'ai recopié le contenu de l'ancien zip (sauf tata.txt) dans le nouveau zip.
    En gros c'est le principe : il faut travailler sur un fichier temporaire et tout recopier...

    Citation Envoyé par Hoegaarden Voir le message
    Je ne suis pas sur qu'en terme de performance ce soit le top car dans mon code je lis 2 fois le toto.zip d'entrée mais bon... Ça fait ce que je veux.
    D'ailleurs si quelqu'un aurait une idée pour l'optimiser je suis preneur.
    Oui le code peut grandement être optimisé et améliorer !

    • Déjà la double lecture est complètement inutile : tu lis une fois le zip pour ajouter les noms dans une liste, puis tu le relis pour recopier les fichiers s'il ne sont pas présent dans cette liste. Il suffit de recopier directement tous les fichiers sauf celui ayant strictement le même nom...
    • Ensuite tu n'utilises pas les try/finally pour les fermetures des flux, ce qui fait qu'en cas d'exception ton fichier reste ouvert et probablement plus modifiable
    • Tu devrais utiliser le même répertoire pour le fichier temporaire. Sinon c'est le fichier temporaire par défaut du système qui est utilisé. Le problème c'est qu'il peut s'agir d'un disque ou d'une partition différente, et que le renameTo() ne pourras alors pas fonctionner.
    • Tu travailles en écriture directement sur le fichier ZIP. En cas d'erreurs tu perds tout (surtout que le fichier temporaire est créé on ne sait où). Il serait préférable de travailler sur le fichier temporaire et de faire la suppression/renommage à la fin si tout s'est bien passé !



    Exemple commenté :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    	public static void addFilesToExistingZip(File zipFile, String filename, boolean fullPath) throws IOException {
     
    		// On crée l'objet File représentant le fichier à insérer dans le ZIP :
    		final File file = new File(filename);
    		// On détermine le nom de l'entré ZIP selon le paramètre 'fullPath' :
    		final String entryName = fullPath ? filename : file.getName();
    		// On crée le fichier temporaire de travail (dans le même répertoire que le ZIP)
    		final File tmpFile = File.createTempFile("tmp", ".zip", zipFile.getParentFile());
    		try {
    			// On ouvre le fichier temporaire en ecriture :
    			final ZipOutputStream output = new ZipOutputStream(new FileOutputStream(tmpFile));
    			try {
    				final byte[] buf = new byte[8192];
    				int len;
     
    				// On ouvre le fichier ZIP en lecture :
    				final ZipInputStream input = new ZipInputStream(new FileInputStream(zipFile));
    				try {
    					ZipEntry entry;
    					// Pour chaque fichier du ZIP :
    					while ( (entry = input.getNextEntry()) != null) {
    						// Si le nom est différent de celui du fichier à ajouter :
    						if (!entryName.equals(entry.getName())) {
    							// On recopie le fichier dans le fichier ZIP temporaire : 
    							output.putNextEntry(new ZipEntry(entry));
    							while ((len = input.read(buf)) > 0) {
    								output.write(buf, 0, len);
    							}
    						}
    					}
    				} finally {
    					input.close();
    				}
     
    				// Puis on ouvre le fichier pour l'ajouter au ZIP :
    				FileInputStream fis = new FileInputStream(file);
    				try {
    					output.putNextEntry(new ZipEntry(entryName));
    					while ((len = fis.read(buf)) > 0) {
    						output.write(buf, 0, len);
    					}
    				} finally {
    					fis.close();
    				}
     
    			} finally {
    				output.close();
    			}
     
    			// Si on arrive ici c'est que tout s'est bien passé
    			// => On supprime le fichier ZIP pour le remplacer par le fichier temporaire :
    			if ( ! (zipFile.delete() && tmpFile.renameTo(zipFile)) ) {
    				throw new IOException("Unable to replace " + zipFile);
    			}
    		} finally {
    			// On force la suppression du fichier temporaire s'il existe encore
    			// (en cas d'erreur)
    			tmpFile.delete();
    		}
    	}

    a++

  5. #5
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut
    Merci beaucoup adiGuba, ton code marche très bien

    Merci à tous.

    A bientôt
    Nicolas

  6. #6
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut
    Bonjour à tous,

    Bon je comprends plus rien,

    Hier j'avais testé le code du post de dessus et tout marchais nickel. Et aujourd'hui après avoir faut un peu de ménage ben ca marche plus.
    Voici l'erreur
    invalid entry compressed size
    Il me sort cette erreur quand il veut copie les fichiers de toto.zip dans le fichier tmp.zip.
    Une idée ?

    Merci de votre aide

  7. #7
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut
    Re bonjour à tous,

    J'espère que vous avez passé un bon week end
    De mon côté je galère toujours autant avec l'erreur du post précédent. Je n'arrive pas à m'en sortir. Dois-je créer un nouveau post ?

    Merci de votre aide.

  8. #8
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Attention que, avec ce système, si tu modifies un zip déjà vérolé tu accumules les ennuis ! Pars d'un zip neuf comme source !

    Peut être aussi serai-je dubitatif sur output.putNextEntry(new ZipEntry(entry)), essaie avec output.putNextEntry(new ZipEntry(entry.getName())), mais je m'y connais pas terrib il faudrait que adiGuba confirme / infirme, j'ai simplement peur que l'entry valide dans la source deviennent invalide dans la destination mais ça dépend comment le système se débrouille j'y connais rien j'ai pas vu jé sé pô.

  9. #9
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gifffftane Voir le message
    Attention que, avec ce système, si tu modifies un zip déjà vérolé tu accumules les ennuis ! Pars d'un zip neuf comme source !
    Ben si le fichier original est vérolé on ne pourra pas aller bien loin dans tous les cas...

    Citation Envoyé par gifffftane Voir le message
    Peut être aussi serai-je dubitatif sur output.putNextEntry(new ZipEntry(entry)), essaie avec output.putNextEntry(new ZipEntry(entry.getName()))
    Oui le problème doit venir de là : je ne sais pas pourquoi j'ai utilisé le constructeur de copie

    Comme on réencode derrière il faut utiliser une Entry vierge quand aux infos de compression...

    a++

  10. #10
    Membre habitué Avatar de Hoegaarden
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2004
    Messages : 362
    Points : 175
    Points
    175
    Par défaut
    Effectivement ça marche mieux avec ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    output.putNextEntry(new ZipEntry(entry.getName()))
    Je vous remercie tous les deux pour votre aide
    Je vais enfin pouvoir passer à l'étape suivante

    Nicolas

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 11/02/2011, 15h21
  2. Ajouter un fichier dans un zip
    Par Ptikir dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 24/03/2009, 15h02
  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, 18h36
  4. [LabView 8.20] Ajouter un fichier dans un zip
    Par Gaorr dans le forum LabVIEW
    Réponses: 0
    Dernier message: 19/09/2007, 15h59
  5. Réponses: 1
    Dernier message: 15/06/2006, 16h17

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