[英]java try finally block to close stream
我想在finally塊中關閉我的流,但它拋出一個IOException
所以我似乎必須在finally
塊中嵌套另一個try
塊才能關閉流。 這是正確的方法嗎? 看起來有點笨重。
這是代碼:
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();
}
}
}
此外,如果您使用的是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();
}
看起來有點笨重。
它是。 至少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 ...終於在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中隱藏一個例外,但它在語義上更接近於Java 7中引入的try-with-resources 。
在Java 7中,你可以這樣做......
try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
AutoCloseable
。 close()
。 它被稱為Try with resources語句 。
是的,它很笨拙,丑陋和令人困惑。 一種可能的解決方案是使用Commons IO ,它提供closeQuietly方法。
在本頁右側的“相關”列中有許多問題實際上是重復的,我建議仔細研究這些問題來解決這個問題。
就像提到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。
你最終的方法是正確的。 如果您在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;
}
來源 。 這個樣本對我很有用。
我在你的代碼中注意到的第一件事是你的代碼中缺少大括號{}。 你還需要將r
值初始化為null
因此你需要首先將null值傳遞給object,這樣如果你寫的條件not null
條件檢查並允許你關閉流。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.