Je veux fermer mon flux dans le bloc finally, mais il lance un IOException
il semble donc que je doive imbriquer un autre bloc try
dans mon bloc finally
pour fermer le flux. Est-ce la bonne façon de procéder? Cela semble un peu maladroit.
Voici le code:
public void read() {
try {
r = new BufferedReader(new InputStreamReader(address.openStream()));
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch (IOException readException) {
readException.printStackTrace();
} finally {
try {
if (r!=null) r.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
Cela semble un peu maladroit.
C'est. Au moins l'essai de Java7 avec des ressources corrige cela.
Avant Java7, vous pouvez créer une fonction closeStream
qui l'avale:
public void closeStream(Closeable s){
try{
if(s!=null)s.close();
}catch(IOException e){
//Log or rethrow as unchecked (like RuntimException) ;)
}
}
Ou mettez l'essai ... enfin à l'intérieur de la prise d'essai:
try{
BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
try{
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
}finally{
r.close();
}
}catch(IOException e){
e.printStackTrace();
}
Il est plus détaillé et une exception dans le dernier en masquera un lors de l'essai, mais il est sémantiquement plus proche du try-with-resources introduit dans Java 7.
De plus, si vous utilisez Java 7, vous pouvez utiliser une instruction try-with-resources :
try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException readException) {
readException.printStackTrace();
}
Dans Java 7 vous pouvez le faire ...
try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
AutoCloseable
.close()
appelée à la fin du bloc try.Cela s'appelle un Try with resources statement .
Oui, c'est maladroit, laid et déroutant. Une solution possible consiste à utiliser Commons IO qui propose une méthode closeQuietly .
Il y a un certain nombre de questions dans la colonne "Connexes" sur la droite de cette page qui sont en fait des doublons, je vous conseille de les parcourir pour trouver d'autres moyens de résoudre ce problème.
Comme la réponse mentionnant la bibliothèque Commons IO, la Google Guava Libraries a une méthode d'assistance similaire pour les choses qui sont Java.io.Closeable. La classe est com.google.common.io.Closeables . La fonction que vous recherchez porte le même nom que Commons IO: closeQuietly ().
Ou vous pouvez rouler le vôtre pour fermer un groupe comme celui-ci: Closeables.close (closeable1, closeable2, closeable3, ...):
import Java.io.Closeable;
import Java.util.HashMap;
import Java.util.Map;
public class Closeables {
public Map<Closeable, Exception> close(Closeable... closeables) {
HashMap<Closeable, Exception> exceptions = null;
for (Closeable closeable : closeables) {
try {
if(closeable != null) closeable.close();
} catch (Exception e) {
if (exceptions == null) {
exceptions = new HashMap<Closeable, Exception>();
}
exceptions.put(closeable, e);
}
}
return exceptions;
}
}
Et cela retourne même une carte de toutes les exceptions qui ont été levées ou nulles si aucune ne l'a été.
Votre approche intérieure est enfin correcte. Si le code que vous appelez dans un bloc finally peut éventuellement lever une exception, assurez-vous de le gérer ou de le journaliser. Ne le laissez jamais sortir du bloc enfin.
Dans le bloc catch, vous avalez l'exception - ce qui n'est pas correct.
Merci...
La première chose que j'ai remarquée dans votre code est le crochet {} manquant dans votre code si vous le regardez. vous devez également initialiser la valeur de r
à null
de sorte que vous devez d'abord passer la valeur nulle à l'objet afin que si la condition que vous avez écrite puisse faire not null
contrôle la condition et vous permet de fermer le flux.
public void enumerateBar() throws SQLException {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = getConnection();
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Bar");
// Use resultSet
}
finally {
try {
if (resultSet != null)
resultSet.close();
}
finally {
try {
if (statement != null)
statement.close();
}
finally {
connection.close();
}
}
}
}
private Connection getConnection() {
return null;
}
source . Cet échantillon m'a été utile.