"Hai! Dalam pelajaran hari ini, kita akan melanjutkan perbincangan kita tentang input dan output stream di Java ( Java I/O ). Ini bukan pelajaran pertama tentang topik ini, dan tentunya bukan yang terakhir :) Masukan/keluaran di Jawa.  Kelas FileInputStream, FileOutputStream, dan BufferedInputStream - 1Seperti itu terjadi, bahasa Java menyediakan banyak cara untuk bekerja dengan I/O. Ada beberapa kelas yang mengimplementasikan fungsi ini, jadi kami membaginya menjadi beberapa pelajaran — jadi Anda tidak akan bingung dari awal :) Sebelumnya pelajaran, kami menyentuh BufferedReader, serta kelas abstrak dan beberapa keturunan . Hari ini kita akan mempertimbangkan 3 kelas baru: , , dan  InputStream.OutputStreamFileInputStream FileOutputStreamBufferedInputStream

Kelas FileOutputStream

Tujuan utama kelas FileOutputStreamadalah untuk menulis byte ke file. Tidak ada yang rumit :) FileOutputStreamadalah salah satu implementasi dari OutputStreamkelas abstrak. Di konstruktor, objek kelas ini mengambil jalur ke file target (di mana byte harus ditulis) atau objek File. Kami akan memeriksa contoh masing-masing:

public class Main { 

   public static void main(String[] args) throws IOException { 

       File file = new File("C:\\Users\\Username\\Desktop\\test.txt"); 
       FileOutputStream fileOutputStream = new FileOutputStream(file); 

       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
}
Saat membuat Fileobjek, kami melewati jalur yang diinginkan ke konstruktor. Kita tidak perlu membuatnya terlebih dahulu: jika tidak ada, program akan membuatnya. Anda juga bisa bertahan tanpa membuat objek tambahan, cukup dengan meneruskan string dengan jalur:

public class Main { 

    public static void main(String[] args) throws IOException { 

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt"); 
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Hasil dalam kedua kasus akan sama. Kami dapat membuka file kami dan melihat yang berikut di sana:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Tapi ada satu nuansa di sini. Coba jalankan kode dari contoh di atas beberapa kali berturut-turut. Kemudian lihat di file dan jawab pertanyaan ini: ada berapa baris? Hanya satu. Tapi Anda menjalankan kode beberapa kali. Ternyata datanya ditimpa setiap kali — yang lama diganti dengan yang baru. Apa yang kami lakukan jika itu tidak sesuai dengan kami dan kami perlu menulis secara berurutan ke file? Bagaimana jika kita ingin menulis salam kita ke sebuah file tiga kali berturut-turut? Semuanya sangat sederhana. Karena bahasa tidak dapat mengetahui perilaku apa yang kita perlukan dalam setiap kasus, pembuat FileOutputStreamdapat mengambil parameter tambahan —boolean append. Jika nilainya benar, data akan ditulis ke akhir file. Jika salah (dan secara default salah), semua data lama akan dihapus dan diganti dengan data baru. Mari kita periksa dengan menjalankan kode kita yang telah dimodifikasi tiga kali:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true); 
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!\r\n"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Isi berkas:

Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers!
Nah, itu berbeda! Jangan lupakan fitur ini saat menggunakan kelas I/O. Ada saat ketika saya menghabiskan berjam-jam mengerjakan tugas, memeras otak berjam-jam, mencoba memahami bagaimana data saya menghilang dari file :) Dan tentu saja, sama seperti kelas I/O lainnya, jangan lupa untuk menggunakan close()metode untuk membebaskan sumber daya.

Kelas FileInputStream

Itu FileInputStreammemiliki tujuan yang berlawanan — membaca byte dari sebuah file. Sama seperti FileOutputStreaminherits OutputStream, kelas ini berasal dari InputStreamkelas abstrak. Kami akan menulis beberapa baris teks di file " test.txt " kami:

"So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters"
Masukan/keluaran di Jawa.  Kelas FileInputStream, FileOutputStream, dan BufferedInputStream - 2Di sini tampilannya membaca data dari file menggunakan FileInputStream:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt"); 

       int i; 

       while((i=fileInputStream.read())!= -1){ 

           System.out.print((char)i); 

       } 
   } 
}
Kami membaca satu byte dari file, mengubah byte yang dibaca menjadi karakter dan menampilkannya di konsol. Dan inilah output konsolnya:

So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters

Kelas BufferedInputStream

Saya pikir, mengingat pengetahuan dari pelajaran sebelumnya, Anda dapat dengan mudah mengatakan mengapa kami membutuhkan kelas BufferedInputStreamdan apa kelebihannya dibandingkan FileInputStream:) Kami telah menemukan aliran buffer, jadi coba tebak (atau ingat) sebelum Anda melanjutkan membaca :) Aliran buffer diperlukan terutama untuk mengoptimalkan I/O. Mengakses sumber data, seperti membaca dari file, adalah operasi yang mahal dalam hal kinerja Dan mengakses file untuk membaca setiap byte adalah pemborosan. Itu sebabnya BufferedInputStreammembaca data tidak satu byte pada satu waktu, tetapi dalam blok, dan menyimpannya untuk sementara dalam buffer khusus. Ini memungkinkan kami mengoptimalkan program dengan mengurangi berapa kali kami mengakses file. Mari kita lihat seperti apa ini:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt"); 

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200); 

       int i; 

       while((i = bufferedInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 
   } 
} 
Di sini kita membuat BufferedInputStreamobjek. Konstruktornya mengambil turunan dari InputStreamkelas atau turunannya, begitu FileInputStreamjuga. Sebagai argumen tambahan, dibutuhkan ukuran buffer dalam byte. Berkat argumen ini, data sekarang akan dibaca dari file bukan satu byte sekaligus, tetapi 200 byte sekaligus! Bayangkan betapa kita telah mengurangi jumlah akses file. Untuk membandingkan kinerja, Anda dapat mengambil file teks besar (beberapa megabita teks) dan membandingkan berapa lama waktu yang dibutuhkan dalam milidetik untuk membaca dan menampilkan ke konsol menggunakan FileInputStreamdan BufferedInputStream. Berikut kode yang menunjukkan kedua opsi:

public class Main { 

   public static void main(String[] args) throws IOException { 

       Date date = new Date(); 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf"); 
       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); 

       int i; 
       while((i = bufferedInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 

       Date date1 = new Date(); 
       System.out.println((date1.getTime() - date.getTime())); 
   } 
} 

 
public class Main { 

   public static void main(String[] args) throws IOException { 

       Date date = new Date(); 
       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf"); 

       int i; 
       while((i = fileInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 


       Date date1 = new Date(); 
       System.out.println((date1.getTime() - date.getTime())); 
   }
}
Saat membaca file 1,5 MB di komputer saya, FileInputStreamselesaikan pekerjaan dalam ~3500 milidetik, tetapi BufferedInputStreamkelola dalam ~1700 milidetik. Seperti yang Anda lihat, aliran buffer mengoptimalkan pekerjaan, memotongnya menjadi dua! :) Kami akan terus mempelajari kelas I/O — sampai jumpa lagi!