java try finally блокирует закрытие потока
Я хочу закрыть свой поток в блоке finally, но он бросает IOException
поэтому кажется, что я должен вложить другой try
заблокировать в моем finally
блок, чтобы закрыть поток. Это правильный способ сделать это? Это кажется немного неуклюжим.
вот код:
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();
}
}
}
7 ответов
Это кажется немного неуклюжим.
это. Попробуйте хотя бы java7 с исправления ресурсы.
Pre java7 вы можете сделать closeStream
функция, которая проглатывает его:
public void closeStream(Closeable s){
try{
if(s!=null)s.close();
}catch(IOException e){
//Log or rethrow as unchecked (like RuntimException) ;)
}
}
или поставить попробовать...наконец внутри попробуйте поймать:
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();
}
это более многословно, и исключение в конце концов скроет один в попытке, но семантически ближе к try-with-resources введено в Java 7.
также, если вы используете Java 7, Вы можете использовать оператор 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();
}
в Java 7 Вы можете это сделать...
try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
- объявление переменной в блоке try требует, чтобы она реализовала
AutoCloseable
. - объявление переменной в блоке try также ограничивает ее область действия блок try.
- любая переменная, объявленная в блоке try, будет автоматически
close()
вызывается при выходе блока try.
Это называется попробуйте с помощью инструкции resources.
Да, это неуклюжий, уродливый и запутанный. Одним из возможных решений является использование Commons IO предлагает closeQuietly метод.
в столбце "связанные" справа от этой страницы есть несколько вопросов, которые на самом деле являются дубликатами, я советую просмотреть их для некоторых других способов решения этой проблемы.
Как и ответ, упоминающий библиотеку Commons IO,Google Guava Библиотеки имеет аналогичный вспомогательный метод для вещей, которые являются java.Ио.Закрыто. Класс com.Гугл.обычное.Ио.Близкие. Функция, которую вы ищете, аналогично называется Commons IO: closeQuietly ().
или вы можете свернуть свой собственный, чтобы закрыть кучу, как это: Closeables.закрыть (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;
}
}
и это даже возвращает карта всех исключений, которые были брошены или null, если никто не был.
ваш подход, наконец, правильный. Если код, вызываемый в блоке finally, может вызвать исключение, убедитесь, что вы либо обработали его, либо зарегистрировали. Никогда не позволяйте ему пузыриться из блока finally.
в блоке catch вы проглатываете исключение, которое неверно.
спасибо...
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;
}
источник. Этот образец был полезен для меня.