Unhandled IOException Java

Bonsoir,
je voudrais créer un fichier dans une méthode “actionPerformed” mais un trows n’est pas compatible avec la méthode et un try/catch ne permet pas de fermer le buffer puisque sa portée est limitée au bloc try. createNewFile exige pourtant que je gère une IOException :

[code]public void actionPerformed(ActionEvent e) {
Object source=e.getSource();
if (source == ajoute){
int[] selection = tableau.getSelectedRows();
modele.addsstitre(selection[0],new SousTitre(selection[0], “”,"",""));
}
if (source == crée){
try {

			File sortie = new File("/home/eric/Bureau/stitre") ;
			if (! sortie.exists())	sortie.createNewFile();
			BufferedWriter tampon = new BufferedWriter (new FileWriter (sortie));
		
		    			
			int pointeur = 0;
			do {
				tampon.write(modele.getValueAt(pointeur, 0).toString());
				tampon.newLine();
				tampon.write(modele.getValueAt(pointeur, 2).toString());
				tampon.newLine();
				tampon.write(modele.getValueAt(pointeur, 3).toString());
				tampon.newLine();
				tampon.newLine();
				pointeur++;
			}
			while (true);
		}
		
		catch (ArrayIndexOutOfBoundsException e3){ 
			
		}

// je ne mets pas de catch pour IO parce que je n’en vois pas l’utilité Edit : ah si …
finally {
tampon.close(); // tampon cannot be resolved
}
}
}[/code]

Y a-t-il une solution ?

C’est juste le scope qui pose problème : il faut sortir ta/tes variable(s) du try/catch. En gros :

BufferedWriter tampon = null; try { // ... tampon = new BufferedWriter(...); //... } finally { if (tampon != null) { tampon.close(); } }

+1

Fait gaffe tout de même.
Je vois une boucle infinie (d’ailleurs je vois pas comment on en sort ?) et surtout un accès à une ressource via potentiellement plusieurs processus (je ne connais pas ton contexte mais à vu de nez ActionPerformed peut être appeler plusieurs fois en parallèle). Tu peux avoir les deux erreurs classiques, c’est à dire des écritures sérialisées n’importe comment, mais aussi une erreur à la création du fichier (qui sera passée sous silence du fait que tu ne regarde pas si la méthode à réussie ou pas).

Si tu bosse en Java7 tu peut utiliser les autoclosable pour ne pas avoir à explicitement fermer ton fichier.

Edit :
Je viens de comprendre comment tu sort de ta boucle. Soit tu veut vraiment faire sale et le catch n’est pas nécessaire. Soit tu fait propre (et plus performant) :

for(int pointeur = 0; pointeur < modele.getRowCount(); ++pointeur) {
    for(int pointeur2 = 0; pointeur < 3; ++pointeur2) {
        tampon.write(modele.getValueAt(pointeur, pointeur2).toString());
        tampon.newLine();
    }
    tampon.newLine();
}

C’est concis (2 fois plus cours si on compte ton catch), tu n’a pas l’impression de te répéter (c’est donc plus facile à maintenir et tu n’a pas de copier-coller), c’est moins sujet aux erreurs et c’est plus lisible grâce à l’utilisation d’une boucle faites pour l’itération. J’ai considéré que tu voulais traiter spécifiquement les 3 premières colonnes, mais si tu veut toutes les gérer il suffit de remplacer 3 par modele.getColumnCount() pour ne plus avoir à faire évoluer ce bout de code à chaque fois que tu fait évoluer modele.

Mais le tampon.close génère aussi l’exception IO et doit se trouver dans le {try}

Bien vu le .getRowCount, je n’ai pas encore les bons réflexes !

Merci à vous :023

Mais le tampon.close génère aussi l’exception IO et doit se trouver dans le {try}[/quote]
Rajoute un try/catch autour ! On n’est plus à ça près… :mrgreen:

try { BufferedWriter tampon = null; try { // ... tampon = new BufferedWriter(...); //... } finally { if (tampon != null) { tampon.close(); } } } catch (...) { }

[code]if (source == crée){

		try {
			
			File sortie = new File("/home/eric/Bureau/stitre") ;
			if (! sortie.exists()){
				sortie.createNewFile();    			
				BufferedWriter tampon = new BufferedWriter (new FileWriter (sortie));
		    		    			
				for(int pointeur = 0; pointeur < modele.getRowCount(); ++pointeur) {
					for (int col=0 ; col< modele.getColumnCount() ; col++){
						if (col!=1){    				
							tampon.write(modele.getValueAt(pointeur, col).toString());
							tampon.newLine();
						}
					}
					tampon.newLine();    				
				}
				tampon.close();
			}
		}
		
		catch (IOException io){ 
			
		}[/code]

Je ne connais pas bien Java mais ça m’étonnerait beaucoup que tampon.write() et tampon.newLine() ne lancent pas d’exception si tampon.close() en lance une. Et si ils lancent effectivement une exception alors ton code est faux et tu ne peux pas éviter un double try.

Je ne comprends pas ce que tu veux dire :

Mes tampon.write .newLine et .close sont bien dans un bloc try.

par ailleurs, mon code fonctionne.

[Edit] : ou alors tu as posté sans lire le post précédent où le try/catch (ArrayIndexOutOfBoundsException e3) avait disparu, mais le double try ne résout de toute façon pas le problème de portée de “tampon”.

Le problème c’est que si l’un des write lève une exception ton fichier n’est pas fermé tout simplement.

Il n’y a pas 800 000 façon de faire en standard.

Version Java 6 :

[code] if (source == cree) {
BufferedWriter tampon = null;
try {

            File sortie = new File("/home/eric/Bureau/stitre");
            if (!sortie.exists()) {
                sortie.createNewFile();
            }
            tampon = new BufferedWriter(new FileWriter(sortie));

            for (int pointeur = 0; pointeur < modele.getRowCount(); ++pointeur) {
                for (int col = 0; col < modele.getColumnCount(); ++col) {
                    if (col != 1) {
                        tampon.write(modele.getValueAt(pointeur, col).toString());
                        tampon.newLine();
                    }
                }
                tampon.newLine();
            }
        } catch (IOException io) {
            try {
                if (tampon != null) {
                    tampon.close();
                }
            } catch (IOException ex) {
            }
        }
    }[/code]

En Java 7 :

[code] if (source == cree) {
try (BufferedWriter tampon = Files.newBufferedWriter(Paths.get("/home/eric/Bureau/stitre"),
Charset.defaultCharset())){

            for (int pointeur = 0; pointeur < modele.getRowCount(); ++pointeur) {
                for (int col = 0; col < modele.getColumnCount(); ++col) {
                    if (col != 1) {
                        tampon.write(modele.getValueAt(pointeur, col).toString());
                        tampon.newLine();
                    }
                }
                tampon.newLine();
            }
        }
        catch(IOException ex) {}
    }[/code]

Files (regarde par là pourquoi il est bien utile), Paths et le try-with-resources sont quand même pratique, non ?

Enfin c’est une pure question de style mais pour l’interieur de la boucle j’écrirais plutôt :

if (col != 1) continue; tampon.write(modele.getValueAt(pointeur, col).toString()); tampon.newLine();
ça évite une indentation disgracieuse (je trouve que pour le regard on à tendance à zapper le if juste après deux for).

J’ai rentré ton code et il fonctionne mais comment le tampon se ferme-t-il puisque le close est dans le catch ?
Et ne faut-il pas éviter le recours aux branchements ? (continue)

Pour ma part j’aurais mis le “close” dans un bloc “finally” :whistle:

Vous avez raison je devais être fatigué (pour la version JSE6).