Di sebelah artikel sebelumnya, kami akan terus belajar operasi aliran byte di Java.
Dekorator Buffered Stream BufferedInput/OutputStream
Aliran dekorator sebenarnya adalah aliran file IO berdasarkan pola desain "mode dekorator", dan aliran buffer kami hanyalah salah satunya. Mari kita lihat.
Sebelum ini, kami menggunakan file baca dan tulis FileInputStream dan FileOutputStream baik baca dan tulis dari disk atau byte, yang sangat memakan waktu.
Aliran buffer kami dapat membaca sebelumnya jumlah byte dari kapasitas yang ditentukan dari disk sekaligus ke dalam memori, dan operasi baca berikutnya akan dibaca langsung dari memori untuk meningkatkan efisiensi. Mari kita lihat implementasi spesifik dari aliran buffered:
Mari kita ambil bufferedInputStream sebagai contoh terlebih dahulu, mari kita sebutkan secara singkat properti intinya:
BUF adalah array byte yang digunakan untuk pembacaan buffering. Nilainya akan diisi terus menerus saat aliran dibaca, dan operasi baca selanjutnya dapat langsung didasarkan pada array buffer ini.
Default_buffer_size Menentukan ukuran buffer default, yaitu, panjang array buf. MAX_BUFFER_SIZE Menentukan batas atas buffer.
Hitung poin ke indeks byte valid terakhir dalam array buffered. POS menunjuk ke posisi indeks byte berikutnya yang akan dibaca.
MarkPos dan Marklimit digunakan untuk mengulangi operasi baca.
Selanjutnya, mari kita lihat beberapa contoh konstruktor bufferedInputStream:
public bufferedInputStream (inputStream in) {this (in, default_buffer_size);} public bufferedInputStream (inputStream in, int int) {super (in); if (size <= 0) {lempar IllegalArgumentException baru ("Ukuran buffer <= 0"); } buf = byte baru [ukuran];}Secara keseluruhan, yang pertama hanya perlu lulus dalam inputstream inputstream yang "didekorasi" dan menggunakan buffer dengan ukuran default. Yang terakhir dapat secara eksplisit menunjukkan ukuran buffer.
Selain itu, Super (IN) menyimpan inputStream ini ke dalam bidang atribut di kelas induk filterInputStream, dan semua operasi baca disk aktual dikeluarkan oleh inputStream ini.
Mari kita lihat operasi baca yang paling penting dan bagaimana penyangga diisi.
Int read () yang disinkronkan publik () melempar ioException {if (pos> = count) {fill (); if (pos> = count) return -1; } return getBufifopen () [pos ++] & 0xff;}Saya percaya semua orang sudah terbiasa dengan metode ini. Itu membaca byte berikutnya dari aliran dan mengembalikannya, tetapi implementasinya dalam detail masih sedikit berbeda.
Hitung titik ke posisi berikutnya dari indeks byte yang valid dalam array buffered, dan POS menunjuk ke posisi berikutnya dari indeks byte yang akan dibaca. Secara teori, POS tidak bisa lebih besar dari jumlah, paling sama.
Jika POS sama dengan Count, itu berarti bahwa semua byte yang valid dalam array buffer telah dibaca. Pada saat ini, data "tidak berguna" dalam buffer perlu dibuang dan batch data baru dimuat ulang dari disk untuk mengisi buffer.
Bahkan, metode pengisian adalah apa yang dilakukannya. Ini memiliki banyak kode, jadi saya tidak akan membawa Anda untuk menguraikannya. Jika Anda memahami fungsinya, mungkin mudah untuk menganalisis implementasinya.
Jika POS masih sama dengan Count setelah metode pengisian dipanggil, itu berarti bahwa inputstream tidak membaca data apa pun dari aliran, yaitu, tidak ada data dalam aliran file untuk dibaca. Untuk ini, lihat baris 246 metode pengisian.
Secara umum, jika buffer berhasil diisi, metode baca kami akan mengambil byte langsung dari buffer dan mengembalikannya ke penelepon.
Public Synchronized int Read (byte b [], int off, int len) {// .....}Metode ini juga merupakan "kenalan", tidak lagi memiliki penjelasan yang tidak perlu, implementasinya serupa.
Metode lewati digunakan untuk melewatkan jumlah byte dengan panjang yang ditentukan untuk membaca aliran file yang berkelanjutan:
Publik Sinkronisasi Long Skip (Long N) {// ......}Satu hal yang perlu diperhatikan adalah bahwa metode Skip mencoba untuk melewatkan byte, tetapi tidak dijamin akan melewatkan n byte. Metode ini mengembalikan jumlah byte yang sebenarnya dilewati. Jika sisa byte yang tersedia dalam susunan buffer kurang dari N, jumlah aktual byte yang dapat dilewati dalam array buffered pada akhirnya akan dilewati.
Akhirnya, mari kita bicara tentang metode dekat ini:
public void close () melempar IOException {byte [] buffer; while ((buffer = buf)! = null) {if (bufupdater.compareandset (ini, buffer, null)) {inputStream input = in; di = null; if (input! = null) input.close (); kembali; } // else coba lagi jika buf baru dikeluarkan dalam fill ()}}Metode Tutup akan mengosongkan aliran "didekorasi" dan memanggil metode dekatnya untuk melepaskan sumber daya yang relevan, yang pada akhirnya akan menghapus ruang memori yang ditempati oleh array buffer.
BufferedInputStream menyediakan kemampuan buffering baca, sementara bufferedOutputStream menyediakan kemampuan buffering menulis, yaitu, operasi penulisan memori tidak akan diperbarui ke disk segera, dan akan disimpan sementara dalam buffer, dan akan ditulis bersama ketika buffer penuh.
Byte Buf yang dilindungi []; Hitungan int yang dilindungi;
BUF mewakili buffer internal, dan jumlah mewakili kapasitas data aktual dalam buffer, yaitu, jumlah byte efektif di buf, daripada panjang array buf.
public bufferedOutputStream (outputStream out) {this (out, 8192);} public bufferedOutputStream (outputStream out, ukuran int) {super (out); if (size <= 0) {lempar IllegalArgumentException baru ("Ukuran buffer <= 0"); } buf = byte baru [ukuran];}Dengan ide implementasi yang sama, perlu untuk menyediakan instance aliran output outputstream, dan juga dapat secara selektif menunjukkan ukuran buffer.
public disinkronkan void write (int b) melempar ioException {if (count> = buf.length) {flushBuffer (); } buf [count ++] = (byte) b;}Metode tulis pertama -tama akan memeriksa apakah buffer masih dapat mengakomodasi operasi penulisan ini. Jika operasi penulisan disk tidak dapat dimulai, semua data buffer akan ditulis ke file disk, jika tidak buffer akan ditulis ke buffer terlebih dahulu.
Tentu saja, bufferedOutputStream juga menyediakan metode flush untuk menyediakan antarmuka ke luar, yaitu, Anda tidak perlu menunggu sampai buffer penuh sebelum menulis data ke disk. Anda juga dapat secara eksplisit memanggil metode ini untuk menghapus buffer dan memperbarui file disk.
void flush publik yang disinkronkan () melempar ioException {flushBuffer (); out.flush ();}Mengenai aliran buffered, konten inti diperkenalkan seperti di atas. Ini adalah aliran yang secara signifikan dapat meningkatkan efisiensi. Melalui itu, jumlah akses disk dapat dikurangi dan efisiensi eksekusi program dapat ditingkatkan.
Kami tidak akan membahas aliran serialisasi objek ObjectInput/OutputStream dan Decorator Stream Datainput/OutputStream berdasarkan tipe dasar. Ketika kita belajar serialisasi, kita akan membahas dua aliran byte ini lagi.
Semua kode, gambar, dan file dalam artikel disimpan di cloud di github saya:
(https://github.com/singleyam/overview_java)
Anda juga dapat memilih untuk mengunduh secara lokal.
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.