2012-01-20 10 views
5

Witam wszystkich Rozumiem, że jeśli czytamy bajty z InputStream i skończymy czytać wszystkie bajty (lub nie zamierzamy czytać do końca strumienia), musimy wywołać close(), aby zwolnić zasoby systemowe powiązane ze strumieniem.Czy strumienie są automatycznie zamykane w przypadku błędu?

Teraz zastanawiałem się, czy mogę read bajtów i rzuca java.io.IOException, czy nadal muszę zadzwonić pod numer close(), aby zwolnić zasoby systemowe związane ze strumieniem?

Czy to prawda, że ​​w przypadku błędów strumienie są zamykane automatycznie, więc nie musimy dzwonić pod numer close()?

+0

Zasoby są zamknięte gdy GCed. W związku z tym możesz mieć problem, który rzadko rzuca wyjątek w pracy. W przypadku deterministycznego zarządzania zasobami funkcja close() powinna być zawsze wywoływana. –

+0

@PeterLawrey Mówisz, że to **, ponieważ ** GC po cichu zjada wyjątek IOException przez 'close()', który powinniśmy nazwać 'close()' sami? Więc jeśli (hipotetycznie) interfejs close() nie rzuca żadnej formy wyjątku, nie musimy wywoływać close(), gdy strumień ma błąd? – Pacerier

+0

Jest to coś, co należy wziąć pod uwagę, jednak dość powszechną praktyką jest zignorowanie wyjątku wygenerowanego przez close(). Problem z zezwoleniem GC na to, że możesz uruchomić nasze uchwyty plików zanim wyzwolisz GC, który wyczyści te zasoby. Twój program może działać, ale czasami kończy się niepowodzeniem i jest to coś, czego chcesz uniknąć. –

Odpowiedz

6

Sam system operacyjny może zamknąć strumienie i zwolnić zasoby, ponieważ proces (a mianowicie JVM) zostaje zakończony, ale nie jest do tego zobowiązany.

Powinieneś zawsze wdrożyć blok finally, w którym zamykasz go w takich przypadkach, np. tak:

InputStream is = null; 

try { 
    is = new FileInputStream(new File("lolwtf")); 
    //read stuff here 
} catch (IOException e) { 
    System.out.println("omfg, it didn't work"); 
} finally { 
    is.close(); 
} 

To naprawdę nie jest gwarantowane do pracy, jeśli rzucił w pierwszej kolejności, ale prawdopodobnie będziesz chce zakończyć w tym momencie i tak ponieważ źródło danych jest zapewne zawiedli w jakiś sposób. Możesz dowiedzieć się więcej informacji na ten temat, jeśli zachowasz dostawcę InputStream wokół, na przykład, jeśli zatrzymam obiekt o numerze File w moim przykładzie, mogę sprawdzić, czy istnieje itp. Za pośrednictwem interfejsu File, ale to jest specyficzne do twojego konkretnego dostawcy danych.

Taktyka ta staje się bardziej użyteczny z sesji sieciowych rzucać, na przykład, z Hibernate ...

+0

Co masz na myśli przez ostatni akapit? Czy masz na myśli taktykę * "implementowania finally block" *? – Pacerier

+0

@Pacerier Znaczy to, że dość często umieszcza się, na przykład, zamknięcie sesji Hibernate w bloku finally. – TC1

Powiązane problemy