簡體   English   中英

java嘗試finally塊來關閉流

[英]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
}
  • 在try塊中聲明變量需要它實現AutoCloseable
  • 在try塊中聲明變量也會將其范圍限制為try塊。
  • try塊中聲明的任何變量將在try塊退出時自動調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM