1: BufferedWriter
1. Pengantar Fungsi Kelas:
BufferedWriter, aliran output karakter cache, fungsinya adalah untuk menyediakan fungsi cache untuk aliran output karakter yang mendasari. Demikian pula, saat menggunakan aliran output karakter yang mendasarinya untuk menulis karakter atau array karakter ke tujuan, koneksi ke tujuan harus dibuka setiap kali ditulis. Akses yang sering terjadi secara konstan efisien, dan juga dapat menyebabkan kerusakan tertentu pada media penyimpanan. Misalnya, ketika kita terus -menerus menulis byte ke disk, dibesar -besarkan untuk menulis unit G yang sangat besar ke file tertentu pada disk, dan jika kita tidak menulis byte, saluran ke disk ini harus dibuka sekali. Hasil ini tidak diragukan lagi menakutkan. , dan ketika kami menggunakan BufferedWriter untuk membungkus aliran output karakter yang mendasarinya, seperti Filereader, kami dapat menulis karakter terlebih dahulu ditulis ke dalam file dalam program ke ruang cache bawaan dari BufferedWriter, dan kemudian ketika jumlah tertentu tercapai, itu akan ditulis ke dalam aliran Filereader pada satu waktu. Pada saat ini, filereader dapat membuka saluran dan menulis blok data ini ke file. Meskipun tidak mungkin untuk mencapai efek menulis semua data ke disk dalam satu akses, itu juga sangat meningkatkan efisiensi dan mengurangi jumlah akses disk! Ini adalah signifikansinya. Prinsip kerjanya yang spesifik disebutkan secara singkat di sini: mungkin cukup membingungkan di sini. Anda dapat melihat kode sumber secara detail. Jika Anda tidak mengerti, maka lihat kembali ke sini. Setiap kali Anda menulis karakter atau array karakter ke dalam bufferedwriter dalam program ini, Anda akan memeriksa apakah array buf karakter yang di -cache (ukuran buf adalah default atau ditentukan saat membuat BW, umumnya default digunakan) penuh. Jika tidak penuh, karakter ditulis ke dalam buf. If it is full, the underlying writer(char[] b, int off, int is called. len) Write all characters in buf to the underlying out at one time, if the character array is written, if the buf is full, the same as the processing when it is full above, if the written character array can be stored, then store it in buf, if the characters to be stored, and the number of characters to be written to buf is less than the length of buf, then write all Karakter di buf yang akan ditulis ke luar, dan kemudian simpan karakter yang akan ditulis di buf (penyimpanan dari subscript 0), jika karakter yang akan dituliskan melebihi panjang buf, lalu tulis langsung ke luar,
2. Pengantar API BufferedWriter:
A: Kata kunci penulis pribadi keluar; Aliran output karakter bawah CB CB []; Buffer Array Private Int Nchars, NextChar; NCHAR-Ukuran ukuran NCHARS, NextChar-Subskrip Karakter berikutnya dalam CB Private Static Int DefaultCharbufferSize = 8192; Ukuran CB Default Private String LinesEparator; Karakter baru, digunakan untuk metode baru. Platform yang berbeda memiliki nilai yang berbeda. B: Metode Konstruk BufferedWriter (Writer Out) membuat BufferedWriter BW menggunakan ukuran CB default. BufferedWriter (penulis out, int sz) membuat bufferedwriter BW menggunakan ukuran CB default. C: Metode umum membatalkan tutup () menutup aliran ini dan melepaskan sumber daya yang terkait dengan aliran ini. void flushbuffer () Flush Karakter yang di -cache dalam CB ke dalam yang mendasarinya, void flush () menyegarkan aliran ini, dan menyegarkan aliran yang mendasari void newline () menulis karakter garis baru. void write (int c) menulis satu karakter ke dalam CB. void write (char cbuf [], int off, int len) Tulis panjang karakter len dari subscript ke cb void write (string s, int, int len) tulis bagian dari string ke cb
3. Analisis Kode Sumber
Paket com.chy.io.original.code; impor java.io.ioException; impor java.io.printwriter;/*** Memberikan fungsi buffering untuk aliran output karakter dan meningkatkan efisiensi. Anda dapat menggunakan karakter yang ditentukan untuk buffer ukuran array atau karakter default untuk buffer ukuran array. */kelas publik BufferedWriter memperluas penulis {// array base array private writer out; // Buffer Array Private Char CB []; // nchars-jumlah total karakter dalam CB, nextChar-subskrip karakter berikutnya dalam cb private int nchars, nextChar; // Ukuran CB default Private static int defaultCharbufferSize = 8192; /*** string pemisah garis. Ini adalah nilai properti line.separator * pada saat aliran dibuat. * Line Newline Character, Digunakan untuk Metode Newline. Platform yang berbeda memiliki nilai yang berbeda. */ Private String LinesEparator; /*** Buat BufferedWriter BW dengan ukuran CB default. */ Public BufferedWriter (Writer out) {this (out, defaultCharbufferSize); } / ** * Buat BR dan inisialisasi bidang terkait dengan ukuran CB yang ditentukan * / Public BufferedWriter (penulis keluar, int sz) {super (out); if (sz <= 0) melempar baru ilegalArargumentException ("Ukuran buffer <= 0"); this.out = out; cb = char baru [sz]; nchars = sz; nextchar = 0; // Dapatkan representasi karakter baru di bawah platform yang berbeda. lineParator = (string) java.security.accesscontroller.doprivileged (sun.security.action.action.actpropertyaction ("line.separator"); } / ** Mendeteksi apakah aliran output karakter yang mendasarinya ditutup* / void privat PasteOpen () melempar ioException {if (out == null) lempar ioException baru ("stream tertutup"); } /*** Siram karakter yang di -cache di CB ke yang mendasarinya, tetapi tidak menyiram karakter dalam yang mendasarinya. * Dan bersihkan CB. */ void flushBuffer () melempar ioException {disinkronkan (lock) {pasteopen (); if (nextChar == 0) kembali; out.write (CB, 0, NextChar); nextChar = 0;}} /*** Tulis satu karakter ke CB. */ public void write (int c) melempar ioException {disinkronkan (lock) {pasteopen (); if (nextchar> = nchars) flushbuffer (); CB [nextChar ++] = (char) c;}} /** * Metode kecil kami sendiri, untuk menghindari memuat java.lang.math jika kami telah menjalankan * keluar dari deskriptor file dan kami mencoba mencetak jejak tumpukan. */ private int min (int a, int b) {if (a <b) return a; return b; } / *** Tulis panjang karakter Len dari subskrip ke CB* / public void write (char cbuf [], int off, int len) melempar ioException {disinkronkan (kunci) {pasteopen (); if ((off <0) || (off> cbuf.length) || (len <0) || ((off + len)> cbuf.length) || ((off + len) <0)) {lempar indexOutofboundsException (); } lain jika (len == 0) {return; } if (len> = nchars) {/* Jika len lebih besar dari panjang CB, maka karakter yang ada dalam CB dan karakter di CBUF ditulis langsung, alih -alih menulis ke CB, dan kemudian menulis ke luar. */flushBuffer (); out.write (cbuf, off, len); return; } int b = off, t = off + len; while (b <t) {int d = min (nchars - nextchar, t - b); system.arraycopy (cbuf, b, cb, nextChar, d); b += d; nextChar += d; if (nextChar> = nchars) flushBuffer (); }}} / *** Tulis bagian dari string ke cb* / public void write (string s, int, int len) melempar ioException {disinkronkan (kunci) {pasteopen (); int b = off, t = off + len; while (b <t) {int d = min (nchars - nextchar, t - b); s.getchars (b, b +d, cb, nextChar); b += d; nextChar += d; if (nextChar> = nchars) flushBuffer (); }}} /*** Tulis garis baru. */ public void newline () melempar ioException {write (lineParator); } / *** Segarkan aliran ini dan refresh aliran yang mendasari pada saat yang sama* / public void flush () melempar ioException {disinkronkan (kunci) {flushBuffer (); out.flush ();}} /*** Tutup aliran ini dan rilis sumber daya yang terkait dengan aliran ini. */ public void close () melempar ioException {disinkronkan (lock) {if (out == null) {return; } coba {flushBuffer (); } akhirnya {out.close (); keluar = null; CB = NULL; }}}}4. Contoh Demonstrasi: Gunakan BufferedReader berikut untuk mengimplementasikan penyalinan file tipe karakter.
Dua: BufferedReader
1. Pengantar Fungsi Kelas:
Stream input karakter buffered, fungsinya adalah untuk menyediakan fungsi buffering untuk aliran input karakter yang mendasari. Ini akan membaca karakter dalam aliran input karakter yang mendasari (dalam) ke buffernya sendiri (array karakter cache bawaan), dan kemudian program memanggil metode baca buferedReader untuk membaca karakter dalam buffer ke dalam program. Ketika karakter dalam buffer dibaca, BufferedReader akan membaca blok data berikutnya dari dalam dan ke dalam buffer agar program dibaca sampai data masuk adalah dibaca. Manfaat melakukan ini adalah, pertama, meningkatkan efisiensi membaca, dan kedua, mengurangi jumlah koneksi untuk membuka media penyimpanan. Untuk alasan terperinci, BufferedWriter yang disebutkan di bawah ini. Ada metode utama pengisian (), yaitu untuk mengisi data dari dalam dan mengisi data dari buffer setiap kali data dalam buffer dibaca sepuluh kali lebih cepat daripada yang dibaca dari disk! Ini adalah peningkatan efisiensi yang sangat menakutkan. Pada saat yang sama, kami tidak dapat menentukan ukuran buffer dari BufferedReader tanpa melarang. Bagaimanapun, butuh waktu lama untuk membaca dalam satu kali. Kedua, harga memori relatif mahal. Yang bisa kita lakukan adalah mencoba menemukan poin yang masuk akal di dalamnya. Secara umum, kita tidak perlu khawatir tentang hal itu dan menggunakan ukuran default buffer saat membuat BufferedReader.
2. Pengantar API BufferedReader:
A: Metode Membangun BufferedReader (pembaca dalam, int sz) membuat BufferedReader berdasarkan ukuran yang ditentukan dan aliran input karakter yang mendasari. BR BufferedReader (pembaca dalam) Gunakan ukuran default untuk membuat aliran buffered dari aliran output yang mendasari B: Metode umum void tutup () Tutup aliran ini dan melepaskan semua sumber daya yang terkait dengan aliran batal ini (int readaheadlimit) menandai posisi retin ini). dapat membaca karakter int read () membaca satu karakter dan kembali dalam bentuk integer. Jika akhir masuk dibaca, ia kembali -1. int read (char [] cbuf, int off, int len) baca karakter len di cbuf mulai dari subscript off, panjang len string readline () baca garis lompat panjang (long n) buang karakter di cbuf
3. Analisis Kode Sumber
Paket com.chy.io.original.code; import java.io.ioException;/*** Tambahkan array buffering karakter CB untuk aliran input karakter yang mendasarinya. Tingkatkan efisiensi * @Version 1.1, 13/11/17 * @authorandychen */kelas publik BufferedReader memperluas pembaca {pembaca pribadi di; Private Char CB []; private int nchars, nextchar; int private static int int tidak valid = -2; private static final int unmarked = -1; private int markedchar = tidak ditandai; private int readaheadlimit = 0; /*Hanya valid saat Markedchar> 0*// ** Jika karakter berikutnya adalah umpan baris, lewati*/ private boolean skiplf = false; / ** Bendera Skiplf Ketika tanda diatur*/ private boolean markedskiplf = false; private static int defaultCharbufferSize = 8192; private static int defaultExpectedlinEllength = 80; /*** Buat BufferedReader berdasarkan ukuran yang ditentukan dan aliran input karakter yang mendasari. BR */ Public BufferedReader (pembaca di, int sz) {super (in); if (sz <= 0) melempar baru ilegalargumentException ("ukuran buffer <= 0"); this.in = in; cb = arang baru [sz]; nextChar = nchars = 0; } / *** Gunakan ukuran default untuk membuat aliran buffered dari aliran output yang mendasarinya* / public bufferedReader (pembaca di) {this (in, defaultCharBufferSize); } / ** Mendeteksi apakah aliran input karakter yang mendasarinya ditutup* / void privat pasteopen () melempar ioException {if (in == null) melempar ioException baru ("stream tertutup"); } /*** Isi CB. */ private void fill () melempar ioException {int dst; if (MarkedChar <= unmarked) {/ *tidak ada tanda */ dst = 0;} else {/ *ditandai */ int delta = nextChar - MarkedChar; if (delta> = readaheadLimit) {/ * lewat batas baca-ahead: markas mark */markedchar = tidak valid; readaheadlimit = 0; dst = 0; } else {if (readaheadlimit <= cb.length) { / * shuffle dalam buffer saat ini * / system.arraycopy (cb, markedchar, cb, 0, delta); Markedchar = 0; dst = delta;} else { / * reallocate buffer untuk mengakomodasi batas baca-ahead * / char ncb [] = char baru [readaheadlimit]; System.ArrayCopy (CB, Markedchar, NCB, 0, Delta); CB = NCB; Markedchar = 0; dst = delta;} nextchar = nchars = delta; }} int n; do {n = in.read (cb, dst, cb.length - dst);} while (n == 0); if (n> 0) {nchars = dst + n; nextChar = dst;}} /*** Baca satu karakter dan kembalikan sebagai bilangan bulat. Jika akhir masuk dibaca, ia kembali -1. */ int read public () melempar ioException {disinkronkan (lock) {pasteOpen (); untuk (;;) {if (nextchar> = nchars) {fill (); if (nextchar> = nchars) return -1;} if (skiplf) {skiplf = false; if (cb [nextchar] == '/n') {nextChar ++; lanjutkan; }} return cb [nextChar ++]; }}} /*** Baca karakter len di dalam ke cbuf dari panjang len mulai dari subscript off* /private int read1 (char [] cbuf, int, int len) melempar ioException {if (nextChar> = no no coopy dan do -no no coundse dan jika tidak ada feed, dan tidak ada yang lebih besar dan tidak ada bekas, dan tidak ada bekas, dan tidak ada bekas, dan tidak ada bekas, dan tidak ada bekas, dan tidak ada bekas, dan tidak ada bekas, dan tidak ada. karakter ke buffer lokal. Dengan cara ini aliran buffered akan mengalir tanpa berbahaya. */ if (len> = cb.length && markedchar <= unmarked &&! skiplf) {return in.read (cbuf, off, len); } fill ();} if (nextChar> = nchars) return -1; if (skiplf) {skiplf = false; if (cb [nextchar] == '/n') {nextChar ++; if (nextChar> = nchars) fill (); if (nextChar> = nchars) return -1; }} int n = math.min (len, nchars - nextChar); System.arraycopy (cb, nextChar, cbuf, off, n); nextchar += n; return n; } / *** Baca karakter len di dalam ke cbuf ke len len dari indeks off dari subscript off* / public int read (char cbuf [], int off, int len) melempar ioException {disinkronkan (kunci) {pasteopen (); if ((off <0) || (off> cbuf.length) || (len <0) || ((off + len)> cbuf.length) || ((off + len) <0)) {lempar indexOutofboundsException (); } else if (len == 0) {return 0; } int n = read1 (cbuf, off, len); if (n <= 0) return n; while ((n <len) && in.ready ()) {int n1 = read1 (cbuf, off + n, len - n); if (n1 <= 0) break; n + = n1; } return n;}} / *** Baca baris dari dalam dan abaikan garis istirahat* / string readline (boolean ignorelf) melempar ioException {stringBuffer s = null; int startchar; disinkronkan (kunci) {pasteopen (); boolean omitlf = Ignorelf || skiplf; bufferloop: for (;;) {if (nextChar> = nchars) fill (); if (nextChar> = nchars) { / * eof * / if (s! = null && s.length ()> 0) return s.toString (); elsereturn null;} boolean eol = false; char c = 0; int i; / * Lewati sisa '/n', jika perlu */if (omitlf && (cb [nextChar] == '/n')) nextChar ++; skiplf = false; omitlf = false; charloop: untuk (i = nextChar; i <nchars; i ++) {c = cb [i]; if ((c == '/n') || (c == '/r')) {eol = true; break charloop; }} startChar = nextChar; nextChar = i; if (eol) {string str; if (s == null) {str = string baru (cb, startchar, i - startChar); } else {S.Append (CB, StartChar, I - StartChar); str = s.tostring (); } NextChar ++; if (c == '/r') {skiplf = true; } return str;} if (s == null) s = new StringBuffer (defaultExpectedlinEllength); S.Append (CB, StartChar, i - startChar); }}} / ** * Baca baris dari dalam, * / public string readline () melempar ioException {return readline (false); } / *** Buang n karakter di dalam* / loncatan panjang publik (long n) melempar ioException {if (n <0l) {lempar baru ilegalargumentException ("Nilai Skip adalah negatif");} disinkronkan (kunci) {pasteopen (); long r = n; while (r> 0) {if (nextchar> = nchars) fill (); if (nextChar> = nchars)/ * eof */ break; if (skiplf) {skiplf = false; if (cb [nextChar] == '/n') {nextChar ++; }} long d = nchars - nextChar; if (r <= d) {nextChar += r; r = 0; break;} else {r -= d; nextChar = nchars;}} return n - r;}} / ** * Tentukan apakah CB kosong atau apakah ada karakter yang dapat dibaca dalam. / * * Jika Newline perlu dilewati dan char berikutnya yang akan dibaca * adalah karakter baru, maka lewati saja. */ if (skiplf) {/ * Perhatikan bahwa in.ready () akan mengembalikan true jika dan hanya jika berikutnya * dibaca pada aliran tidak akan diblokir. */if (nextChar> = nchars && in.ready ()) {fill ();} if (nextChar <nchars) {if (cb [nextChar] == '/n') nextChar ++; skiplf = false;}} return (nextChar <nchars) || in.ready ();}} / *** Tentukan apakah aliran ini mendukung tanda* / boolean publik markasported () {return true; } /*** Tandai posisi aliran ini saat ini, dan izinkan membaca ke karakter yang readaheadLimit sebelum panggilan untuk mengatur ulang metode gagal. */ mark public void (int readaheadLimit) melempar ioException {if (readaheadlimit <0) {lempar baru ilegalargumentException ("batas baca-ahead <0");} disinkronkan (lock) {pasteopen (); this.readaheadlimit = readaheadlimit; MarkedChar = NextChar; MarkedSkiplf = skiplf;}} /*** Setel ulang posisi di mana masuk terakhir ditandai. Artinya, karakter berikutnya dibaca dari posisi yang ditandai terakhir. */ public void reset () melempar ioException {disinkronkan (lock) {pasteopen (); if (markedchar <0) lempar ioException baru ((markedchar == tidak valid)? "Mark tidak valid": "stream tidak ditandai"); NextChar = MarkedChar; skiplf = MarkedSkiplf;}} // Tutup aliran ini dan lepaskan semua sumber daya yang terkait dengan aliran public void close () ini melempar ioException {disinkronkan (kunci) {if (in == null) return; melampirkan(); di = null; cb = null;}}}4. Contoh demonstrasi:
Paket com.chy.io.original.test; impor java.io.bufferedReader; impor java.io.bufferedwriter; impor java.io.file; classcepier java.io.filereader; impor java.filewriter; impor java.io.filewriter; {/** * The test of these two classes here is relatively simple, which is to wrap the file character stream and implement file copying* If you are interested, you can test the efficiency, be lazy, and ignore it*/public static void main(String[] args) throws IOException{File resouceFile = new File("D://test.txt");File targetFile = new File ("e: //copyoftest.txt"); bufferedReader br = BufferedReader baru (filereader baru (resoucefile)); bufferedwriter bw = Bufferedwriter baru (filewriter baru (targetFile)); char [] cbuf = char baru [1024]; int n = 0; who (n = n = n. -1) {bw.write (cbuf, 0, n);} // Jangan lupa untuk menyegarkan dan menutup aliran, jika tidak sumber daya tidak akan dirilis pada waktunya di satu sisi, dan di sisi lain, dapat menyebabkan kehilangan data jika Br.Close (); bw.flush (); bw.close ();}}Meringkaskan:
Untuk BufferedReader dan BufferedWriter, esensinya adalah menambahkan fungsi buffering ke input karakter dan aliran output yang mendasarinya, pertama -tama membaca atau menulis data dalam aliran yang mendasarinya dalam bentuk kelompok bacaan sekaligus, dan kemudian beroperasi pada buffer. Ini bukan hanya efisiensi, tetapi juga menghemat sumber daya. Akhirnya, dalam program, untuk alasan efisiensi, kedua kelas ini harus digunakan untuk aliran tingkat rendah untuk menghiasnya, alih-alih hanya memegang aliran dan secara langsung mengunggahnya, berpikir bahwa mereka dapat direalisasikan.