1. InputStreamReaderkelas

Satu lagi ciri strim yang menarik ialah anda boleh menggabungkan berbilang strim bersama-sama menjadi rantaian . Strim boleh membaca data bukan sahaja daripada sumber data dalamannya, tetapi juga daripada aliran lain .

Ini adalah mekanisme yang sangat berkuasa di Java, yang memungkinkan untuk mencipta senario pembacaan data yang kompleks dengan menyambungkan satu aliran ke yang lain. Skim sedemikian kelihatan seperti ini:

Kelas InputStreamReader

Apabila atur cara membaca data daripada aliran data, aliran data pula membaca data daripada sumber datanya, contohnya aliran data atau fail lain.

Apatah lagi, setiap aliran data bukan sahaja membaca masuk dan mengeluarkan data, tetapi juga boleh mengubahnya atau melakukan pelbagai operasi padanya. Contoh yang baik bagi "aliran perantaraan" sedemikian ialah InputStreamReaderkelas.

Kita sudah mengetahui kelas yang dipanggil FileReader— ia adalah Readeryang membaca data daripada fail. Dan dari mana InputStreamReaderdatanya diperoleh? Betul — daripada sebuah InputStream.

Apabila anda mencipta InputStreamReaderobjek, anda perlu memasukkan InputStreamobjek atau salah satu daripada kelas turunannya. Contoh:

String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);

Kelas InputStreamReadermempunyai semua kaedah yang Readerdimiliki oleh kelas, dan ia berfungsi dengan cara yang sama.

Perbezaan utama antara InputStreamReaderkelas dan, katakan, FileReaderialah tempat mereka membaca data. FileReadermembaca data daripada fail (duh — itulah sebabnya ia dipanggil FileReader), tetapi InputStreamReadermembaca data daripada fail InputStream.

Apabila anda membaca aksara daripada FileReaderobjek menggunakan read()kaedah, ia seterusnya membaca dua bait daripada fail pada cakera dan mengembalikannya sebagai chars.

Apabila anda membaca aksara daripada InputStreamReaderobjek menggunakan read()kaedah, ia seterusnya membaca dua bait daripada FileInputStreamobjek yang dihantar kepadanya, yang seterusnya membaca data daripada fail. Hasilnya ialah rangkaian panggilan kepada read()kaedah.


2. BufferedReaderkelas

Satu lagi kelas menarik yang mungkin anda sering gunakan ialah BufferedReader. Ini juga merupakan "strim perantaraan" yang membaca data daripada aliran lain.

Seperti namanya, BufferedReaderkelas ialah subkelas Readerdan membolehkan anda membaca aksara . Tetapi apa yang paling menarik ialah anda juga perlu memberikannya sumber data dalam bentuk aliran dari mana aksara boleh dibaca , iaitu aliran yang mewarisi Readerkelas.

Apa gunanya? Tidak seperti InputStreamReader, BufferedReaderkelas tidak menukar bait kepada aksara: ia tidak menukar apa-apa sama sekali. Sebaliknya, ia menimbal data .

Apabila atur cara membaca satu aksara daripada BufferedReaderobjek, objek itu membaca susunan besar aksara daripada aliran sumbernya sekaligus. Dan menyimpannya secara dalaman.

Apabila aksara seterusnya dibaca daripada BufferedReaderobjek, ia hanya mengambil aksara seterusnya daripada tatasusunan penimbal dalamannya dan mengembalikannya tanpa mengakses sumber data. Hanya apabila semua aksara dalam penimbal habis, ia akan dibaca dalam susunan besar aksara yang lain.

Kelas ini BufferedReaderjuga mempunyai kaedah yang sangat berguna — String readLine(), yang membolehkan anda membaca keseluruhan rentetan data daripada aliran sumber sekaligus. Anda boleh menggunakan kaedah ini untuk, katakan, membaca fail dan memaparkan kandungannya pada skrin baris demi baris. Contoh:

Kami secara khusus menulis beberapa kod padat untuk menggambarkan betapa mudahnya ini. Kod ini juga boleh ditulis dengan lebih terperinci.

String src = "c:\\projects\\log.txt";

try(FileReader in = new FileReader(src);
BufferedReader reader = new BufferedReader(in))
{
   while (reader.ready())
   {
      String line = reader.readLine();
      System.out.println(line);
   }
}
Buat FileReaderobjek. Sumber data ialah fail.
Buat BufferedReaderobjek. Sumber data ialah FileReader.
Selagi masih ada data dalam pembaca
Baca satu baris
Paparkan baris tersebut
Satu perkara penting:

Jika anda merangkaikan berbilang aliran, maka close()kaedah itu hanya perlu dipanggil pada salah satu daripadanya. Strim itu akan memanggil kaedah pada sumber datanya, dan seterusnya, sehingga close()dipanggil pada aliran data akhir.



3. Membaca daripada konsol

Dan satu lagi fakta menarik: Scannerkelas tidak lebih daripada aliran input perantaraan yang membaca data daripada System.in, yang juga merupakan aliran data.

Berikut ialah dua cara untuk membaca baris daripada konsol:

Kelas pengimbas Kelas BufferedReader dan BufferedWriter
InputStream stream = System.in;
Scanner console = new Scanner(stream);
String line = console.nextLine();
InputStream stream = System.in;
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buff = new BufferedReader(reader);
String line = buff.readLine();

Rakan kita tidak lebih daripada pembolehubah statik kelas . Ia adalah yang namanya .System.ininSystemInputStreamin

Jadi hampir dari awal kajian Java anda tentang CodeGym, anda telah bekerja dengan aliran data dan membina rantai daripadanya. Tetapi sekarang anda akan melakukannya dengan lebih sedar.