1 klasaInputStreamReader
Kolejną interesującą cechą wątków jest możliwość łączenia wielu wątków w łańcuchy. Wątek może odczytywać dane nie tylko ze źródła danych, które je przechowuje, ale także z innego wątku.
Jest to bardzo potężny mechanizm w Javie, który umożliwił konstruowanie złożonych scenariuszy odczytu danych poprzez łączenie jednego strumienia z drugim. Taki schemat wygląda następująco:

Gdy program odczytuje dane ze strumienia danych, z kolei odczytuje je ze swojego źródła danych: na przykład innego strumienia danych lub pliku.
Jednocześnie każdy strumień danych nie tylko odczytuje i przekazuje dane, ale także może je przekształcać lub wykonywać na nich różne operacje. Dobrym przykładem takiego „pośredniego przepływu” danych jest plik InputStreamReader.
Znamy już klasę o nazwie FileReader, a jest nią Reader, która odczytuje dane z pliku. Skąd klasa odczytuje dane InputStreamReader? Zgadza się: ze strumienia InputStream.
Aby utworzyć obiekt typu InputStreamReader, musisz przekazać do niego obiekt typu lub jego następcę klasy InputStream. Przykład:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
Klasa InputStreamReaderma wszystkie metody, które ma klasa Reader, i działają one dokładnie w ten sam sposób.
Główna różnica między klasami InputStreamReaderi, na przykład, FileReaderpolega na tym, skąd odczytują dane. FileReaderodczytuje dane z pliku (dlatego nazywa się FileReader), ale InputStreamReaderodczytuje dane ze strumienia InputStream.
Gdy odczytujesz znak z obiektu FileReadertą metodą read(), on z kolei odczytuje dwa bajty z pliku na dysku i zwraca je jako char.
Gdy odczytujesz znak z obiektu InputStreamReaderza pomocą metody read(), obiekt z kolei odczytuje dwa bajty z przekazanego mu obiektu FileInputStream, który z kolei odczytuje dane z pliku. Okazuje się taki łańcuch wywołań metod read().
2. KlasaBufferedReader
Jest jeszcze jedna interesująca klasa, której prawdopodobnie będziesz często używać — BufferedReader. Jest to również „wątek pośredni”, który odczytuje dane z innego wątku.
Klasa BufferedReader, jak sama nazwa wskazuje, jest klasą, która dziedziczy po znakach Readeri umożliwia ich odczytywanie . Jednak co najciekawsze, jako źródło danych trzeba do niego również przekazać strumień, z którego można odczytać znaki – strumień, który dziedziczy po klasie Reader.
O co chodzi? W przeciwieństwie do InputStreamReader„a, klasa BufferedReadernie konwertuje bajtów na znaki: w ogóle niczego nie konwertuje. Zamiast tego buforuje dane .

Gdy program odczytuje BufferedReaderpojedynczy znak z obiektu, jednocześnie odczytuje dużą tablicę znaków ze swojego strumienia źródłowego. I trzyma je w środku.
Podczas odczytywania następnego znaku z obiektu BufferedReaderpo prostu pobiera następny znak z wewnętrznej tablicy buforów i zwraca go bez odwoływania się do strumienia źródła danych. I tylko wtedy, gdy wszystkie znaki w buforze się skończą, ponownie odczyta dużą tablicę znaków.
Klasa BufferedReaderposiada również bardzo przydatną metodę - String readLine(), która pozwala odczytywać dane ze strumienia źródłowego od razu w liniach. Za pomocą tej metody można na przykład odczytać plik i wyświetlić jego zawartość na ekranie linia po linii. Przykład:
Celowo napisaliśmy kod w zwartym formacie, abyś mógł zobaczyć, jakie to może być wygodne. Możesz napisać ten kod bardziej szczegółowo.
|
Tworzymy obiekt FileReader, źródłem danych jest plik. Tworzymy obiekt BufferedReader, źródłem danych jest obiekt FileReader; dopóki readerdane są nadal dostępne Przeczytaj jedną linię Wyświetl linię na ekranie |
Jeśli połączyłeś kilka strumieni w łańcuch, wystarczy wywołać metodę close()tylko na jednym z nich: wywoła ją na swoim źródle danych i tak dalej, aż dotrze do końcowego strumienia danych.
3. Odczyt z konsoli
I jeszcze jeden ciekawy fakt: klasa Scannerto nic innego jak przychodzący pośredni strumień danych, który odczytuje je ze strumienia System.in- także strumienia danych.
Oto dwa sposoby odczytania wiersza z konsoli:
| Klasa skanera | klasy BufferedReader i InputStreamReader |
|---|---|
|
|
Nasza słynna zmienna to nic innego jak statyczna zmienna klasowa . Jego typ to , a jego nazwa to .System.ininSystemInputStreamin
Tak więc prawie od samego początku nauki Javy na CodeGym pracujesz ze strumieniami danych i budujesz z nich łańcuchy. Dopiero teraz zrobisz to bardziej świadomie.
GO TO FULL VERSION