2015-04-17 21 views
5

Say mam następujący fragmentJak zwraca kod 500 statusu jeśli jest IOException podczas czytania

public boolean checkListing() { 

    try { 

     // open the users.txt file 
     BufferedReader br = new BufferedReader(new FileReader("users.txt")); 

     String line = null; 
     while ((line = br.readLine()) != null) { 
      String[] values = line.split(" "); 
      // only interested for duplicate usernames 
      if (username.equals(values[0])) { 
       return true; 
      } 
     } 
     br.close(); 
     return false; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     // what to do here 
    } 

} 

Jak należy sobie radzić w błąd, jeśli wystąpi wyjątek? Chcę wiedzieć, że tak się stało i zwrócić użytkownikowi 500 kodu.

Czy powinienem rzucić i zrobić wyjątek i złapać go w drugiej grupie?

Czy istnieje bardziej elegancki sposób na uzyskanie opinii na ten temat?

+1

1) wyrzuć wyjątek z początkowym wyjątkiem jako przyczynę; 2) użyj złożonego obiektu '{wynik, kod, przyczyna niepowodzenia}' do zwrócenia.Wolę 1), ponieważ jest zarówno elegancki, jak i użyteczny: z dowolnego miejsca wykonania można uzyskać pełny ślad niepowodzenia. –

+0

@SashaSalauyou Dzięki za odpowiedź. Mam jednak problem ze zrozumieniem. Czy możesz dać mi źródło, aby przeczytać więcej o drugiej drodze? – Rentonie

+0

BTW nie zapomnij zamknąć 'br' w' finally' bloku, w przeciwnym razie sekwencja awarii może spowodować wyciek zasobów. –

Odpowiedz

1

Możesz powrócić instancję tej klasy:

public class Result { 

    private boolean errorOccurs; 
    private boolean isValid; 
    private Exception exception; 

    public Result(boolean isValid){ 
     this(isValid, false, null); 
    } 

    public Result(boolean isValid, boolean errorOccurs, Exception exception){ 
     this.isValid = isValid; 
     this.errorOccurs = errorOccurs; 
     this.exception = exception; 
    } 

    public boolean isValid(){ 
     return isValid; 
    } 

    public boolean errorOccurs(){ 
     return errorOccurs; 
    } 

    public Exception getException(){ 
     return exception; 
    } 
} 

W twoim przypadku:

public Result checkListing() { 

    try { 

     // open the users.txt file 
     BufferedReader br = new BufferedReader(new FileReader("users.txt")); 

     String line = null; 
     while ((line = br.readLine()) != null) { 
      String[] values = line.split(" "); 
      // only interested for duplicate usernames 
      if (username.equals(values[0])) { 
       return new Result(true); 
      } 
     } 
     br.close(); 
     return new Result(false); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return new Result(false, true, e); 
    } 
} 

a krótki formularz klasy Wynik :)

public class Result { 
    public boolean errorOccurs; 
    public boolean isValid; 
    public Exception exception; 
} 
+0

Dokładnie to, czego szukałem. Dziękuję bardzo za odpowiedź na pytanie, proszę pana. – Rentonie

+0

Ale nadal nie zamykaj 'BufferedReader' i' FileReader' na końcu ... –

+1

Tak! Zawsze zamykaj wszystkich czytelników :) –

0

W tym przypadku IOException można wyrzucić z readLine lub close.

Ten wyjątek oznacza, że ​​wystąpiła wyjątkowa sytuacja, na przykład źródło strumienia nie jest już dostępne. Twój program można odzyskać lub ponownie odczytać źródło lub zgłosić ten problem użytkownikowi.

Decyzja o tym, co należy zrobić, zależy od Twojej logiki, nie ma tu preferowanego sposobu.

Należy pamiętać, że należy zamknąć br w bloku finally.

0

lepszy sposób jest wyłączenie wyjątku opakowania:

try (FileReader fr = new FileReader("users.txt")) { 
    try (BufferedReader br = new BufferedReader(fr)) { 

     // ... do your work 

    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
} catch (IOException e1) { 
    throw new RuntimeException(e1); 
} 

Zauważ, że tutaj otwieram zasoby w instrukcjach try, tym samym powodując ich automatyczne zamykanie po zakończeniu wykonywania, nie zależne od wyniku wykonania.

0

Dwie najczęściej spotykane metody, jakie widziałem, to - jak zauważył Sasha Salauyou - rethrow (potencjalnie zawinięty) lub oddzielny obiekt dostarczający więcej informacji.

Podstawowym problemem, który próbujesz rozwiązać, jest to, że masz metodę, która ma zwracać więcej niż dwie wartości z typem zwracanym, który może wyrażać tylko dwa. Musisz więc zwrócić typ, który obsługuje wszystkie możliwe wartości zwracane, lub musisz znaleźć alternatywne ścieżki powrotu (np. Wyjątki).

W moim własnym kodzie, chciałbym raczej faworyzować tutaj rewanż. Pisanie dedykowanego obiektu powrotu staje się trudne do utrzymania długoterminowego z IO, ponieważ istnieje wiele różnych sposobów, które mogą zawieść. Odejdę jednak od sugerowanej trasy (wyjątek z pierwotnym wyjątkiem), ponieważ zazwyczaj nie ma silnego powodu do zawijania. Wystarczy zadeklarować metodę checkListing, aby rzucić wyjątek IOException, zarejestrować komunikat lub stacktrace w bloku catch, a następnie wyrzucić oryginalny wyjątek.

Powiązane problemy