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 InputStreamReader
ma 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 InputStreamReader
i, na przykład, FileReader
polega na tym, skąd odczytują dane. FileReader
odczytuje dane z pliku (dlatego nazywa się FileReader
), ale InputStreamReader
odczytuje dane ze strumienia InputStream
.
Gdy odczytujesz znak z obiektu FileReader
tą metodą read()
, on z kolei odczytuje dwa bajty z pliku na dysku i zwraca je jako char
.
Gdy odczytujesz znak z obiektu InputStreamReader
za 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 Reader
i 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 BufferedReader
nie konwertuje bajtów na znaki: w ogóle niczego nie konwertuje. Zamiast tego buforuje dane .
Gdy program odczytuje BufferedReader
pojedynczy 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 BufferedReader
po 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 BufferedReader
posiada 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 reader dane 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 Scanner
to 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.in
in
System
InputStream
in
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