"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 :) Seperti 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
.OutputStream
FileInputStream
FileOutputStream
BufferedInputStream
Kelas FileOutputStream
Tujuan utama kelasFileOutputStream
adalah untuk menulis byte ke file. Tidak ada yang rumit :) FileOutputStream
adalah salah satu implementasi dari OutputStream
kelas 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 File
objek, 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 FileOutputStream
dapat 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
ItuFileInputStream
memiliki tujuan yang berlawanan — membaca byte dari sebuah file. Sama seperti FileOutputStream
inherits OutputStream
, kelas ini berasal dari InputStream
kelas 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"
Di 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 kelasBufferedInputStream
dan 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 BufferedInputStream
membaca 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 BufferedInputStream
objek. Konstruktornya mengambil turunan dari InputStream
kelas atau turunannya, begitu FileInputStream
juga. 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 FileInputStream
dan 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, FileInputStream
selesaikan pekerjaan dalam ~3500 milidetik, tetapi BufferedInputStream
kelola dalam ~1700 milidetik. Seperti yang Anda lihat, aliran buffer mengoptimalkan pekerjaan, memotongnya menjadi dua! :) Kami akan terus mempelajari kelas I/O — sampai jumpa lagi!
GO TO FULL VERSION