2011-08-28 29 views
27

finallyブロックでストリームを閉じたいが、IOExceptionがスローされるので、finallyブロックを別のブロックに入れてストリームを閉じる必要があるようだ。それはそれを行う正しい方法ですか?それはちょっとしたようです。java 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(); 
     } 
    } 


} 
+0

可能な複製[ネストされたtry/catchブロックが優先されますか?](http://stackoverflow.com/questions/183499/is-there-a-preference-for-nested-try-catch-blocks) –

答えて

19

これはちょっとしたようです。

です。少なくとも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{ 
    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(); 
} 

それはより冗長だと例外で最終的には試しに1つを隠しますが、意味的にはJava 7で導入されたtry-with-resourcesに近づいています。

+0

私はより清潔で読みやすいので、2番目のアプローチを行った。これはメモリリークを避けたいので、本当に重要です。 – Akshay

8

はい、それは、不格好醜いと紛らわしいです:

は、ここでは、コードです。考えられる解決策の1つはメソッドを提供するCommons IOを使用することです。

このページの右側の[関連]欄には実際に重複しているいくつかの質問がありますが、この問題を扱う他の方法を調べることをおすすめします。

2

正しい。 finallyブロックで呼び出したコードが例外をスローする可能性がある場合は、そのコードを処理するか、またはログに記録してください。最終的にブロックから泡立たせてはいけません。

catchブロック内で例外を飲み込んでいますが、これは正しくありません。また

おかげで...

32

は、Java 7を使用している場合、あなたはtry-with-resources statementを使用することができます。

のJava 7では
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(); 
}   
20

あなたがこれを行うことができます...

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 statementと呼ばれています。

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。

+0

誰にでも私の答えを落として投票した人に、なぜそれから学ぶことができるのか説明してください。 –

+0

私はあなたがそれをバランスをとるようにアップアップします。グアバは素晴らしい図書館です – thaspius

0
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。 このサンプルは私にとって役に立ちました。

+0

ありがとうございます。更新しました。 –

関連する問題