1. OutputStreamkelas

Kami baru sahaja meneroka aliran input. Sudah tiba masanya untuk bercakap tentang aliran keluaran.

Kelas OutputStreamialah kelas induk untuk semua kelas yang menyokong output bait. Ini ialah kelas abstrak yang tidak melakukan apa-apa dengan sendirinya, tetapi ia mempunyai kelas turunan untuk setiap kesempatan.

Kedengarannya sangat rumit. Untuk meletakkannya dengan lebih mudah, kelas ini beroperasi pada bait, dan bukan, sebagai contoh, aksara atau jenis data lain. Dan hakikat bahawa ia adalah abstrak bermakna bahawa kita biasanya tidak menggunakannya, sebaliknya salah satu daripada kelas keturunannya. Contohnya, FileOutputStreamdan seumpamanya.

Tetapi kembali ke OutputStreamkelas. Kelas ini mempunyai kaedah yang mesti dilaksanakan oleh semua kelas keturunannya. Berikut adalah yang utama:

Kaedah Penerangan
void write(int b)
Menulis satu bait (bukan an int) ke strim.
void write(byte[] buffer)
Menulis tatasusunan bait ke strim
void write(byte[] buffer, off, len)
Menulis sebahagian daripada tatasusunan bait ke strim
void flush()
Menulis semua data yang disimpan dalam penimbal ke strim
void close()
Menutup strim

Apabila anda mencipta objek kelas yang mewarisi InputStream, anda biasanya menentukan objek sumber yang InputStreammembaca data daripadanya. Apabila anda mencipta objek kelas yang mewarisi OutputStream, anda juga biasanya menentukan objek sasaran atau strim yang data akan ditulis.

Mari kita lihat secara ringkas semua kaedah kelas OutputStream:

write(int b)kaedah

Kaedah ini menulis satu bait (bukan an int) kepada aliran keluaran. Nilai yang dihantar dihantar ke bait, dan tiga bait pertama int dibuang.

write(byte[] buffer)kaedah

Menulis tatasusunan bait yang diberikan kepada aliran keluaran. Itu sahaja.

write(byte[] buffer, int offset, int length)kaedah

Menulis sebahagian daripada tatasusunan bait yang diluluskan kepada aliran keluaran. Pembolehubah mengimbangi menunjukkan indeks elemen pertama tatasusunan, dan lengthialah panjang subset yang akan ditulis.

flush()kaedah

Kaedah ini flush()digunakan untuk memaksa mana-mana data yang berpotensi buffer dalam aliran semasa untuk ditulis ke aliran sasaran. Ini berkaitan apabila menggunakan penimbalan dan/atau objek berbilang aliran yang disusun dalam rantai.

close()kaedah

Menulis sebarang data tidak bertulis kepada objek sasaran. Kaedah close()tidak perlu dipanggil jika anda menggunakan try-with-resourcesblok.

Contoh menyalin fail

Kod Catatan
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreamuntuk membaca dari fail
OutputStreamuntuk menulis ke fail

Penampan di mana kita akan membaca data
Selagi terdapat data dalam aliran

Baca data ke dalam penimbal
Tulis data dari penimbal ke aliran kedua

2. Writerkelas

Kelas Writeradalah sama dengan OutputStreamkelas, tetapi hanya satu perbezaan sekali lagi: ia berfungsi dengan aksara ( char) dan bukannya bait.

Ini ialah kelas abstrak: anda tidak boleh mencipta objek kelas Writer. Matlamat utamanya adalah untuk menjadi kelas induk biasa untuk ratusan kelas keturunan dan memberi mereka kaedah biasa untuk bekerja dengan aliran aksara.

Kaedah kelas Writer(dan semua kelas keturunannya):

Kaedah Penerangan
void write(int b)
Menulis satu aksara (bukan satu int) ke strim.
void write(char[] buffer)
Menulis tatasusunan aksara ke strim
void write(char[] buffer, off, len)
Menulis sebahagian daripada tatasusunan aksara ke strim
void write(String str)
Menulis rentetan ke strim
void write(String str, off, len)
Menulis sebahagian daripada rentetan kepada strim
void flush()
Menulis semua data yang disimpan dalam penimbal ke strim
void close()
Menutup strim

Kaedah ini sangat serupa dengan kaedah kelas OutputStream, tetapi ia berfungsi dengan aksara dan bukannya bait.

Penerangan kaedah:

write(int b)kaedah

Kaedah ini menulis satu aksara ( char— bukan an int) kepada aliran keluaran. Nilai yang diluluskan dibuang ke a char, dan dua bait pertama dibuang.

write(char[] buffer)kaedah

Menulis tatasusunan aksara yang diberikan kepada aliran keluaran.

write(char[] buffer, int offset, int length)kaedah

Menulis sebahagian daripada tatasusunan aksara yang diluluskan ke aliran keluaran. Pembolehubah offsetmenunjukkan indeks elemen pertama tatasusunan, dan lengthialah panjang subset yang akan ditulis.

write(String str)kaedah

Menulis rentetan yang diberikan kepada aliran keluaran.

write(String str, int offset, int length)kaedah

Menulis sebahagian daripada rentetan yang diberikan kepada aliran keluaran: rentetan itu ditukar kepada tatasusunan aksara. Pembolehubah offsetmenunjukkan indeks elemen pertama tatasusunan, dan lengthialah panjang subset yang akan ditulis.

flush()kaedah

Kaedah ini flush()digunakan untuk memaksa mana-mana data yang berpotensi buffer dalam aliran semasa untuk ditulis ke aliran sasaran. Ini berkaitan apabila menggunakan penimbalan dan/atau objek berbilang aliran yang disusun dalam rantai.

close()kaedah

Menulis sebarang data tidak bertulis kepada objek sasaran. Kaedah close()tidak perlu dipanggil jika anda menggunakan try-with-resourcesblok.

Contoh program yang menyalin fail teks:

Kod Catatan
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readeruntuk membaca dari fail
Writeruntuk menulis ke fail

Penampan di mana kita akan membaca data
Selagi terdapat data dalam aliran

Baca data ke dalam penimbal
Tulis data dari penimbal ke aliran kedua

StringWriterkelas

Terdapat satu lagi kelas menarik yang mewarisi Writerkelas: ia dipanggil StringWriter. Ia mengandungi rentetan boleh ubah — StringBufferobjek. Dan setiap kali anda "menulis" sesuatu pada StringWriterobjek, teks itu hanya ditambahkan pada penimbal dalamannya.

Contoh:

Kod Catatan
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
Strim aksara sasaran ( StringWriter) dicipta
Rentetan ditulis kepada penimbal di dalam StringWriter
Rentetan ditulis kepada penimbal di dalam StringWriter

Menukar kandungan objek kepada rentetan

Dalam kes ini, StringWriterkelas pada asasnya ialah pembalut ke atas StringBufferkelas, tetapi StringWriterkelas itu adalah keturunan Writerkelas aliran, dan ia boleh digunakan dalam rantaian objek aliran. Ini adalah harta yang cukup berguna dalam amalan.



3. PrintStreamkelas

Kelas aliran output juga boleh dimasukkan ke dalam rantaian dengan aliran perantara yang menulis data ke aliran sasaran yang dihantar kepada mereka. Pandangan umum interaksi aliran ini kelihatan seperti ini:

Kelas PrintStream

Yang paling menarik dan serba boleh daripada semua aliran keluaran perantaraan ialah PrintStream. Ia mempunyai berpuluh-puluh kaedah dan sebanyak 12 pembina.

Kelas PrintStreammewarisi FilterOutputStreamkelas, yang mewarisi OutputStream. Ini bermakna bahawa PrintStreamkelas mempunyai semua kaedah kelas induk sebagai tambahan kepada kaedahnya sendiri . Berikut adalah yang paling menarik:

Kaedah Penerangan
void print(obj)
Menukar objek yang diluluskan kepada rentetan dan mengeluarkannya kepada aliran sasaran.
void println(obj)
Menukar objek yang diluluskan kepada rentetan dan mengeluarkannya kepada aliran sasaran. Menambah pemisah baris pada penghujung
void println()
Mengeluarkan watak pemisah baris ke aliran sasaran
PrintStream format(String format, args...)
Membina dan mengeluarkan rentetan berdasarkan rentetan format dan hujah yang diluluskan; serupa dengan String.format()kaedah

Dan di manakah berpuluh-puluh kaedah ini, anda bertanya?

Nah, ia mempunyai banyak varian print()dan println()kaedah dengan parameter yang berbeza. Mereka boleh diringkaskan dalam jadual ini.

Kami tidak akan menyelami kaedah ini, kerana anda sudah mengetahuinya dengan baik. Bolehkah anda meneka apa yang saya dapat?

Ingat tak System.out.println()? Tetapi ia boleh ditulis dalam dua baris:

Kod Output konsol
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Perintah kegemaran kami ialah panggilan kepada kaedah pada pembolehubah statik kelas . Dan jenis pembolehubah ini ialah .System.out.println()println()outSystemPrintStream

Dalam banyak peringkat CodeGym, dan dalam hampir setiap tugas, anda telah memanggil kaedah kelas PrintStreamtanpa mengetahuinya!

Penggunaan praktikal

Java mempunyai kelas yang menarik ini dipanggil ByteArrayOutputStream, yang merupakan tatasusunan bait yang berkembang secara dinamik yang mewarisi OutputStream.

Objek ByteArrayOutputStreamdan PrintStreamobjek boleh dirantai seperti ini:

Kod Penerangan
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try(PrintStream stream = new PrintStream(baos))
{
   stream.println("Hello");
   stream.println(123);
}

String result = baos.toString();

System.out.println(result);
Cipta penimbal tulis dalam ingatan

Balut penimbal dalam PrintStreamobjek

Tulis data ke konsol



Tukar tatasusunan kepada rentetan!

Output konsol:
Hello!
123