"Halo, Amigo! Hari ini kita akan sekali lagi menggali cara kerja InputStream dan OutputStream . Penjelasan awal sebenarnya sedikit sederhana. Ini bukan antarmuka. Mereka adalah kelas abstrak, dan mereka bahkan memiliki beberapa metode yang diimplementasikan. Mari kita lihat metode yang mereka miliki:"

metode InputStream Apa yang dilakukan metode ini
int read(byte[] buff);
Metode ini segera membaca satu blok byte ke dalam buffer ( array byte ), hingga buffer penuh atau hingga sumber tidak memiliki byte lagi untuk dibaca.
Metode mengembalikan jumlah byte yang sebenarnya dibaca (yang bisa kurang dari panjang array)
int read();
Metode ini membaca satu byte dan mengembalikannya. Hasilnya diperlebar menjadi int untuk penampilan. Jika tidak ada lagi byte untuk dibaca, metode mengembalikan -1.
int available();
Metode ini mengembalikan jumlah byte yang belum dibaca (tersedia).
void close();
Metode ini «menutup» aliran. Anda menyebutnya setelah selesai bekerja dengan aliran.
Objek kemudian melakukan operasi pembersihan yang diperlukan untuk menutup file, dll.
Pada titik ini, Anda tidak dapat membaca data lagi dari aliran.

"Jadi kita tidak hanya dapat membaca satu byte, tetapi juga seluruh blok?"

"Tepat."

"Bisakah kita juga menulis seluruh blok?"

"Ya, periksalah:"

metode OutputStream Apa yang dilakukan metode ini
void write(int c);
Metode ini menulis satu byte. Jenis int dipersempit menjadi byte. Bagian ekstra dibuang begitu saja.
void write(byte[] buff);
Metode ini menulis satu blok byte.
void write(byte[] buff, int from, int count);
Metode ini menulis bagian dari blok byte. Ini digunakan dalam kasus ketika array byte mungkin tidak terisi seluruhnya.
void flush();
Jika aliran secara internal menyimpan data apa pun yang belum ditulis, metode ini memaksanya untuk ditulis.
void close();
Metode ini «menutup» aliran. Anda menyebutnya setelah selesai bekerja dengan aliran.
Objek kemudian melakukan operasi housekeeping yang diperlukan untuk menutup file, dll. Anda tidak dapat lagi menulis data ke aliran, dan flush dipanggil secara otomatis.

"Seperti apa kode penyalinan file jika kita membaca seluruh blok sekaligus, bukan satu byte?"

"Hmm. Sesuatu seperti ini:"

Salin file di disk
public static void main(String[] args) throws Exception
{
 //Create a stream to read bytes from a file
 FileInputStream inputStream = new FileInputStream("c:/data.txt");
 //Create a stream to write bytes to a file
 FileOutputStream outputStream = new FileOutputStream("c:/result.txt");

  byte[] buffer = new byte[1000];
 while (inputStream.available() > 0) //as long as there are unread bytes
 {
  //Read the next block of bytes into buffer, and store the actual number of bytes read in count.
  int count = inputStream.read(buffer);
  outputStream.write(buffer, 0, count); //Write a block (part of a block) to the second stream
 }

 inputStream.close(); //Close both streams. We don't need them any more.
 outputStream.close();
}

"Saya mengerti segalanya tentang buffer, tapi apa variabel hitungan ini?"

"Saat kita membaca blok data terbaru dari sebuah file, kita mungkin mendapatkan, katakanlah, 328 byte, bukan 1000. Jadi saat kita menulis data, kita perlu menunjukkan bahwa kita tidak menulis seluruh blok—hanya 328 pertama. byte."

Saat kita membaca blok terakhir, metode read akan mengembalikan jumlah byte yang sebenarnya dibaca. 1000 setiap kali kita membaca satu blok, kecuali blok terakhir, ketika kita mendapat 328.

Jadi ketika kita menulis sebuah blok, kita menunjukkan bahwa tidak semua byte dalam buffer harus ditulis, hanya 328 (yaitu nilai yang disimpan dalam variabel count).

"Sekarang semuanya beres. Terima kasih, Ellie."