2011-08-28 10 views
27

Chcę zamknąć mój strumień w bloku finally, ale rzuca IOException, więc wydaje się, że muszę zagnieździć kolejny blok try w moim bloku finally w celu zamknięcia strumienia. Czy to właściwa droga? Wydaje się nieco niezdarny.java spróbować w końcu zablokować, aby zamknąć strumień

Oto kod:

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

możliwy duplikat [Czy istnieje preferencja dla zagnieżdżonych bloków try/catch?] (Http://stackoverflow.com/questions/183499/is-there-a-preference-for-nested-try-catch-blocks) –

Odpowiedz

19

Wygląda na nieco przylegającą.

To jest. Przynajmniej java7 wypróbowuje z poprawkami zasobów.

Pre java7 można dokonać closeStream funkcję, która pożera go:

public void closeStream(Closeable s){ 
    try{ 
     if(s!=null)s.close(); 
    }catch(IOException e){ 
     //Log or rethrow as unchecked (like RuntimException) ;) 
    } 
} 

Albo umieścić wewnątrz wreszcie spróbować ... połowu Spróbuj:

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(); 
} 

To bardziej gadatliwy i wyjątek w ostatecznie ukryje jeden w próbie, ale jest semantycznie bliższy try-with-resources wprowadzony w Javie 7.

+0

Poszedłem z drugim podejściem, ponieważ jest ono bardziej przejrzyste i czytelne. Jest to bardzo ważne, ponieważ chcemy uniknąć wycieków pamięci. – Akshay

8

Tak to jest niezgrabne, brzydki i kłopotliwe. Jednym z możliwych rozwiązań jest użycie metody Commons IO, która oferuje metodę closeQuietly.

W kolumnie "Powiązane" po prawej stronie tej strony znajduje się kilka pytań, które w rzeczywistości są duplikatami, radzę przejrzeć je w celu znalezienia innych sposobów radzenia sobie z tym problemem.

2

Twoje podejście w końcu jest poprawny. Jeśli kod, który wywołujesz w bloku finally, może ewentualnie rzucić wyjątek, upewnij się, że go obsłużysz lub zapisz go. Nigdy nie pozwól, aby bańka wyszła z bloku końcowego.

W bloku catch połkniesz wyjątek - co nie jest poprawne.

Dzięki ...

32

Także jeśli używasz Java 7, można użyć try-with-resources statement:

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

W Javie 7 można to zrobić ...

try (BufferedReader r = new BufferedReader(...)){ 
    String inLine; 
    while ((inLine = r.readLine()) != null) { 
      System.out.println(inLine); 
    } 
} catch(IOException e) { 
    //handle exception 
} 
  • Zgłaszanie zmiennej w bloku try wymaga implementacji AutoCloseable.
  • Zgłaszanie zmiennej w bloku try również ogranicza jej zakres do bloku próbnego .
  • Każda zmienna zadeklarowana w bloku try będzie automatycznie wywoływana pod numerem close() po wyjściu bloku try.

Nazywa się Try with resources statement.

5

Podobnie jak w przypadku odpowiedzi z biblioteki Commons IO, Google Guava Libraries ma podobną metodę pomocy dla rzeczy, które są java.io.Closeable. Klasa to com.google.common.io.Closeables.Funkcja, której szukasz, jest podobnie nazywana Commons IO: closeQuietly().

Albo można toczyć własną rękę, aby zamknąć kilka jak ten: 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; 
    } 
} 

I to nawet zwraca mapę żadnych wyjątków, które były wyrzucony lub zerowy, jeśli żaden nie był.

+0

Do tego, kto nie głosował za moją odpowiedzią, czy mógłbyś wyjaśnić, dlaczego mogę się z niej uczyć? –

+0

Zabiorę cię do równowagi. Guava jest świetną biblioteką – 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. Ta próbka była dla mnie przydatna.

+0

dziękuję. zaktualizowany. –

Powiązane problemy