Builder.build ferme l'InputStream de mon fichier ZIP
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:
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:
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:
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 nud 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());
}
}
} |