0Pricing
Java Academy · Lekcja

Bezpieczne zamykanie strumieni

try-with-resources

Bezpieczne zamykanie strumieni to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Dlaczego zamykać strumienie

Strumienie, takie jak BufferedReader, zajmują zasoby systemowe — uchwyty plików, bufory pamięci i połączenia. Jeśli nigdy ich Pan nie zamknie, zasoby te mogą wyciekać.

Zamknięcie strumienia zwalnia zajmowane przez niego zasoby i opróżnia wszystkie oczekujące dane. W tej lekcji pokazano, jak robić to bezpiecznie.

Metoda close

Każdy czytnik ma metodę close(). Jej wywołanie zwalnia zasób.

W przypadku BufferedReader opakowującego System.in zamknięcie powoduje również zamknięcie opakowanych przez niego strumieni bazowych.

BufferedReader br =
    new BufferedReader(new InputStreamReader(System.in));
// ... use br ...
br.close();

Stary, ryzykowny sposób

Można ręcznie wywołać close(), ale jeśli przed wykonaniem tej linii wystąpi błąd, close() zostanie pominięte, a zasób wycieknie.

Umieszczenie close() w bloku finally pomaga, ale jest rozwlekłe i łatwo popełnić w nim błąd.

BufferedReader br = null;
try {
    br = new BufferedReader(
        new InputStreamReader(System.in));
    // ... use br ...
} finally {
    if (br != null) br.close();
}

try-with-resources

Java oferuje prostsze rozwiązanie: try-with-resources. Deklaruje się strumień w nawiasach po try, a Java automatycznie zamyka go po zakończeniu bloku — nawet jeśli wystąpi błąd.

Bez finally i bez ręcznego close(). To obecnie zalecana praktyka.

try (BufferedReader br =
        new BufferedReader(new InputStreamReader(System.in))) {
    String line = br.readLine();
    System.out.println(line);
}

Jak to działa

Każdy zasób zadeklarowany w nawiasach try (...) musi implementować AutoCloseable. BufferedReader spełnia ten warunek, więc Java wywołuje jego close() za Pana.

Zamknięcie następuje po zakończeniu bloku, niezależnie od tego, czy kończy się on normalnie, czy w wyniku wyjątku.

Pełny przykład

Oto kompletny program używający try-with-resources do odczytania jednego wiersza. Czytnik jest automatycznie zamykany na końcu bloku.

Program odczytuje dane z System.in, więc czeka na dane wejściowe i nie można go tutaj uruchomić automatycznie.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(System.in))) {
            String name = br.readLine();
            System.out.println("Hi " + name);
        }
    }
}

Uruchamialny przykład z StringReader

Aby pokazać, że try-with-resources działa bez wprowadzania danych z klawiatury, w tym przykładzie program odczytuje dane z StringReader. Można go w pełni uruchomić.

Po zakończeniu bloku czytnik jest automatycznie zamykany — nie trzeba samodzielnie zapisywać żadnego wywołania close().

import java.io.BufferedReader;
import java.io.StringReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        try (BufferedReader br =
                new BufferedReader(new StringReader("done"))) {
            System.out.println(br.readLine());
        }
    }
}

Wiele zasobów

W jednym try można zadeklarować kilka zasobów, rozdzielając je średnikami. Java zamyka je wszystkie w odwrotnej kolejności względem kolejności deklaracji.

Jest to przydatne, gdy opakowuje się wiele strumieni.

try (InputStreamReader isr =
        new InputStreamReader(System.in);
     BufferedReader br = new BufferedReader(isr)) {
    System.out.println(br.readLine());
}

Obsługa IOException

Odczyt może spowodować wyjątek IOException. Do bloku try-with-resources można dodać catch, aby go obsłużyć zamiast deklarować throws.

Zasób nadal zostanie automatycznie zamknięty przed wykonaniem bloku catch.

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(System.in))) {
    System.out.println(br.readLine());
} catch (IOException e) {
    System.out.println("Read failed");
}

Czy należy zamykać System.in?

Uwaga: zamknięcie czytnika korzystającego z System.in zamyka również samo System.in, którego nie można ponownie otworzyć.

W krótkich programach nie stanowi to problemu. Jeśli jednak później nadal potrzebuje Pan danych z konsoli, nie należy zamykać tego konkretnego czytnika. Trzeba wiedzieć, co opakowuje dany strumień.

Najlepsze praktyki

Aby bezpiecznie obsługiwać strumienie:

  • Należy preferować try-with-resources zamiast ręcznego close().
  • Mechanizm ten zamyka zasoby automatycznie, nawet gdy wystąpią błędy.
  • Należy pamiętać, że zamknięcie czytnika System.in zamyka standardowe wejście.

Staranna obsługa zasobów zapobiega wyciekom i błędom.

Szybki test

Zastanów się nad główną zaletą try-with-resources.

Podsumowanie

Dowiedział się Pan, dlaczego należy zamykać strumienie, poznał ryzykowne ręczne podejście z użyciem finally oraz przejrzysty wzorzec try-with-resources, który automatycznie zamyka zasoby AutoCloseable.

Może Pan teraz bezpiecznie odczytywać dane wejściowe za pomocą BufferedReader od początku do końca.

Często zadawane pytania

Czy lekcja „Bezpieczne zamykanie strumieni” jest bezpłatna?

Tak — pełny tekst „Bezpieczne zamykanie strumieni” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Bezpieczne zamykanie strumieni”?

try-with-resources Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Bezpieczne zamykanie strumieni”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego BufferedReader
  2. Odczytywanie wierszy
  3. Parsowanie liczb z danych wejściowych
  4. Bezpieczne zamykanie strumieni
← Powrót do Java Academy