Bonjour,
Après plusieurs tentatives et recherches sur le net, je ne suis pas parvenu à résoudre mon problème.

Ce que je veux faire:
Modifier un fichier XML (ajouter des éléments) dans un ZIP qui contient plusieurs autres fichiers.

Solution:
Lire les entrées de mon fichier zip:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
ZipInputStream input = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry entry;
while ( (entry = input.getNextEntry()) != null) {
...
Si c'est le fichier à modifier, je récupère le stream, le parse, ajoute les éléments et reconstruis mon entrée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
Document document = null;
//On crée une instance de SAXBuilder
SAXBuilder sxb = new SAXBuilder();
try{
   //On crée un nouveau document JDOM avec en argument le fichier XML
   //Le parsing est terminé ;)
   document = sxb.build(input);
   ...
Ensuite j'ajoute les entrées dans un ZIP temporaire qui remplacera celui d'origine.

Mon problème:
C'est que la fonction build de SAXBuilder ferme mon input, du coup quand je passe à la prochaine entrée de mon ZIP (boucle while), j'ai l'erreur: java.io.IOException: Stream closed.


Avez-vous une solution à me proposer?



Voici ma classe complète (non terminée):
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package gmo.addclubMember.main;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
 
 
public class Main {
 
	private static final String TEAM_A_XML_FILE = "licencies/equipe_a.xml";
	private static final String OFFICIELS = "licencies/officiels.xml";
 
	public static void main(String[] args) {
		File zipFile = null;
		File tmpFile = null;
		try {
			//On récupère le ZIP d'origine
			zipFile = new File("C:/TestMarque/CD38_38_U17F2_A_4071_ARTAS_BASKET_CLUB_BASKET_DES_VALLONS_DE_LA_TOUR_200000006520036.zip");
			//On crée le ZIP temporaire (dans le même répertoire que le ZIP d'origine)
			tmpFile = File.createTempFile("tmp", ".zip", zipFile.getParentFile());
			try {
				ZipInputStream input = null;
				ZipOutputStream output = null;
				try {
					input = new ZipInputStream(new FileInputStream(zipFile));
					output = new ZipOutputStream(new FileOutputStream(tmpFile));
 
					final byte[] buf = new byte[8192];
					int len;
					ZipEntry entry;
					//On parcours le ZIP d'origine
					while ((entry = input.getNextEntry()) != null) {
						if (entry.getName().equals(TEAM_A_XML_FILE)) {
							//Si on est sur les licencies de l'équipe A
							addCoachMember(input);
						} else if (entry.getName().equals(OFFICIELS)) {
							//Si on est sur les licencies officiels
							addOfficielMember(input);
						}
 
						//On recopie le fichier dans le ZIP temporaire : 
						output.putNextEntry(new ZipEntry(entry));
						while ((len = input.read(buf)) > 0) {
							output.write(buf, 0, len);
						}
					}
				} finally {
					try {
						input.close();
					} catch (Exception ex) {
						//Do nothing
					}
					try {
						output.close();
					} catch (Exception ex) {
						//Do nothing
					}
				}
				//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 ZIP temporaire s'il existe encore
				tmpFile.delete();
			}
		} catch (IOException e1) {
			System.out.println("Erreur dans la création du ZIP temporaire");
			e1.printStackTrace();
		}
	}
 
	private static ZipEntry addCoachMember(InputStream is) {
		SAXBuilder sxb = new SAXBuilder();
		Document document = null;
		try {
			//On crée un nouveau document JDOM avec en argument le fichier XML
			//Le parsing est terminé ;)
			document = sxb.build(is);
 
			//On initialise un nouvel élément racine avec l'élément racine du document.
			Element racine = document.getRootElement();
 
			//Méthode définie dans la partie 3.2. de cet article
			afficheALL(racine);
		} catch (Exception e) {
			//Do nothing
		}
		return null;
	}
 
	private static ZipEntry addOfficielMember(InputStream is) {
		SAXBuilder sxb = new SAXBuilder();
		Document document = null;
		try {
			//On crée un nouveau document JDOM avec en argument le fichier XML
			//Le parsing est terminé ;)
			document = sxb.build(is);
 
			//On initialise un nouvel élément racine avec l'élément racine du document.
			Element racine = document.getRootElement();
 
			//Méthode définie dans la partie 3.2. de cet article
			afficheALL(racine);
		} catch (Exception e) {
			//Do nothing
		}
		return null;
	}
 
	//Ajouter cette méthodes à la classe JDOM2
	private static void afficheALL(Element racine) {
		//On crée une List contenant tous les noeuds "etudiant" de l'Element racine
		List<?> listEtudiants = racine.getChildren("licencies");
 
		//On crée un Iterator sur notre liste
		Iterator<?> i = listEtudiants.iterator();
		while (i.hasNext()) {
			//On recrée l'Element courant à chaque tour de boucle afin de
			//pouvoir utiliser les méthodes propres aux Element comme :
			//sélectionner un nœud fils, modifier du texte, etc...
			Element courant = (Element) i.next();
			//On affiche le nom de l’élément courant
			System.out.println(courant.getChild("licencie").getChild("nom").getText());
		}
	}
}