Java попробуйте, наконец, заблокировать, чтобы закрыть поток
Я хочу закрыть мой поток в блоке 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();
}
}
}
Ответы
Ответ 1
Кажется немного неуклюжим.
Это. По крайней мере, java7 попробуйте с исправлениями ресурсов.
Предварительно java7 вы можете сделать функцию closeStream
, которая проглатывает ее:
public void closeStream(Closeable s){
try{
if(s!=null)s.close();
}catch(IOException e){
//Log or rethrow as unchecked (like RuntimException) ;)
}
}
Или поставьте попытку... наконец, внутри try catch:
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, но оно семантически ближе к try-with-resources, представленному в Java 7.
Ответ 2
Также, если вы используете 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();
}
Ответ 3
В 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, автоматически вызывается
close()
при выходе из блока try.
Он вызвал Попробовать с выражением о ресурсах.
Ответ 4
Да, это неуклюжий, уродливый и запутанный. Одним из возможных решений является использование Commons IO, который предлагает closeQuietly.
В "Связанном" столбце справа от этой страницы есть несколько вопросов, которые на самом деле дублируются, я советую просмотреть их для некоторых других способов решения этой проблемы.
Ответ 5
Как и упоминание библиотеки Commons IO, Google Guava Libraries имеет аналогичный вспомогательный метод для вещей, которые являются java.io.Closeable. Класс com.google.common.io.Closeables. Функция, которую вы ищете, также называется Commons IO: closeQuietly().
Или вы можете свернуть свой собственный, чтобы закрыть связку следующим образом: 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;
}
}
И это даже возвращает карту любых исключений, которые были выбраны или null, если они не были.
Ответ 6
В конечном итоге ваш подход правильный. Если код, который вы вызываете в блоке finally, может вызвать исключение, убедитесь, что вы либо обрабатываете его, либо регистрируете его. Никогда не позволяйте ему пузыриться из блока finally.
В блоке catch вы проглатываете исключение - это неверно.
Спасибо...
Ответ 7
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;
}
.
Этот образец был полезен для меня.