1:BufferedWriter
1。クラス関数の概要:
BufferedWriter、キャッシュ文字出力ストリーム、その機能は、着信基礎となる文字出力ストリームにキャッシュ機能を提供することです。同様に、基礎となる文字出力ストリームを使用して宛先に文字または文字配列を書き込む場合、宛先への接続を書き込むたびに開く必要があります。このような頻繁なアクセスは常に効率的であり、ストレージ媒体に一定の損傷を引き起こす可能性があります。たとえば、ディスクに常にバイトを書き込む場合、ディスク上の指定されたファイルにGの非常に大きなユニットを書き込むことが誇張されており、バイトを書き込まない場合は、このディスクへのチャネルを1回開く必要があります。この結果は間違いなく恐ろしいです。 、そして、bufferedwriterを使用して、Filreaderなどの基礎となる文字出力ストリームをラップすると、最初にバッファレッドライターの組み込みキャッシュスペースにプログラム内のファイルに書き込まれる文字を書き込み、次に一定の金額に到達すると、一度にファイルリーダーのストリームに書き込まれます。この時点で、FilReaderはチャネルを開き、このデータブロックをファイルに書き込むことができます。すべてのデータを1つのアクセスでディスクに書き込む効果を達成することは不可能ですが、効率を大幅に改善し、ディスクアクセスの数を減らします!これがその重要性です。ここでは、その特定の作業原則について簡単に言及しています。ここでは非常に混乱している可能性があります。ソースコードを詳細に見ることができます。わからない場合は、ここを振り返ってください。プログラムのバッファーライターにキャラクターまたはキャラクターの配列を書くときはいつでも、キャッシュされたキャラクターアレイBUF(BUFのサイズがBWを作成するときにデフォルトまたは指定されているかどうか、通常はデフォルトが使用されます)を確認します。いっぱいでない場合、キャラクターはBUFに書き込まれます。それがいっぱいの場合、根本的なライター(char [] b、int off、intは呼ばれます。len)は、BUFのすべてのキャラクターを一度に根底に配置します。文字配列が書かれている場合、BUFがいっぱいの場合、書かれたキャラクターアレイを保存して、BUFのhodでbufの数であるbufの数であるキャラクターがbufに格納されている場合は、bufのnest for for for for for for bufのキャラクターをbufに保存すると、文字配列を保存してからbufに格納する場合、処理と同じです。 bufで書き込み、buf(subscript 0からのストレージ)で書かれている文字を保存します(subscript 0のストレージ)、bufの長さを超えた場合は、直接書き込みます。
2。BufferedWriterAPIの紹介:
A:キーワードプライベートライターアウト。低い文字出力ストリームprivate char cb [];バッファーアレイプライベートインターナチャーズ、NextChar; NCHARS - サイズのサイズ、NCHARS、NEXTCHAR - CB Private Static Int DefaultCharBufferSize = 8192の次の文字のサブススクリプト。デフォルトのCBサイズのプライベート文字列ラインパレーター。 Newlineメソッドに使用されるNewLine文字。プラットフォームが異なると、値が異なります。 B:構成方法BufferedWriter(Writer Out)は、デフォルトのCBサイズを使用してBufferedWriter BWを作成します。 BufferedWriter(Writer Out、Int SZ)は、デフォルトのCBサイズを使用してBufferedWriter BWを作成します。 C:一般的な方法はclose()を閉じます()このストリームを閉じて、このストリームに関連するリソースを解放します。 void flushbuffer()cached文字をcbのキャッシュキャラクターを基礎となるflush()に照らし、void flush()はこのストリームをリフレッシュし、根底にあるストリームvoid newline()がNewlineキャラクターを書き留めます。 void write(int c)は、単一の文字をCBに書き込みます。 void write(char cbuf []、int off、int len)レンの文字の長さをサブスクリプトからcb void write(string s、int off、int len)に書き込みcbに文字列の一部を書き込みます
3。ソースコード分析
パッケージcom.chy.io.original.code; import java.io.ioexception; import java.io.io.io.io.io.io.io.io.printwriter;/***キャラクター出力ストリームにバッファリング機能を提供し、効率を向上させます。指定された文字を使用して、配列サイズまたはデフォルト文字をバッファーしてアレイサイズをバッファすることができます。 */public class BufferedWriterはライターを拡張します{//ベースアレイプライベートライターアウト; //バッファアレイプライベートチャーCB []; // NCHARS-CB、NextCharの文字の総数 - CB Private Int NCHARSの次の文字の添え字、NextChar; //デフォルトのCBサイズprivate static int defaultcharbuffersize = 8192; /***ラインセパレーター文字列。これは、ストリームが作成された瞬間に、line.separator *プロパティの値です。 * NewLineメソッドに使用される新しいライン文字。プラットフォームが異なると、値が異なります。 */ private string lineseparator; /***デフォルトのCBサイズのBufferedWriter BWを作成します。 */ public bufferedwriter(writer out){this(out、defaultcharbufferize); } / ** *指定されたCBサイズで関連フィールドを初期化するBRを作成し、パブリックバッファレッドライター(writer、int sz){super(out); if(sz <= 0)新しいIllegalargumentexception( "Buffer Size <= 0"); this.out = out; cb = new char [sz]; nchars = sz; nextchar = 0; //さまざまなプラットフォームでnewline文字の表現を取得します。 lieseparator =(string)java.security.accessController.doprivileded(new sun.security.action.getPropertyaction( "line.separator")); } / **基礎となる文字出力ストリームが閉じられているかどうかを検出* / private void sureseopen()throws ioException {if(out == null)throw new ioException( "stream closhing"); } /*** CBのキャッシュされたキャラクターを基礎となるように洗い流しますが、根底にあるキャラクターを洗い流しません。 *そしてClear CB。 */ void flushbuffer()throws ioexception {synchronized(lock){surseopen(); if(nextchar == 0)return; out.write(cb、0、nextchar); NextChar = 0;}} /*** CBに単一の文字を書き込みます。 */ public void write(int c)throws ioexception {synchronized(lock){sureseopen(); if(nextchar> = nchars)flushbuffer(); cb [nextchar ++] =(char)c;}} /** * java.lang.mathのロードを避けて、ファイル記述子を実行した場合、スタックトレースを印刷しようとしている場合は、独自の小さな最小メソッド。 */ private int min(int a、int b){if(a <b)return a; return b; } / ***レンの文字の長さをサブスクリプトからcb* / public void write(char cbuf []、int、int len)throws ioexception {synchronized(lock){surseopen(); if((off <0)||(off> cbuf.length)||(len <0)||((off + len)> cbuf.length)||((off + len)<0)){throw new new indexoutofboundsexcection(); } else if(len == 0){return; } if(len> = nchars){/* lenがCBの長さよりも大きい場合、CBの既存の文字とCBUFの文字は、CBに書き込み、その後書き込みに書き込む代わりに直接書き込まれます。 */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(); }}} / ***文字列の一部をcb* / public void write(string s、int off、int len)throws ioexception {synchronized(lock){surseopen(); 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(); }}} /*** newlineを書きます。 */ public void newline()throws ioexception {write(lineseparator); } / ***このストリームを更新して、同時に根底にあるストリームを更新* / public void flush()throws ioException {synchronized(lock){flushbuffer(); out.flush();}} /***このストリームを閉じて、このストリームに関連するリソースをリリースします。 */ public void close()throws ioexception {synchronized(lock){if(out == null){return; } try {flushbuffer(); }最後に{out.close(); out = null; cb = null; }}}}4。デモンストレーションの例:次のBufferedReaderを使用して、文字型ファイルのコピーを実装します。
2:BufferedReader
1。クラス関数の概要:
バッファリングされた文字入力ストリーム、その機能は、着信基になる文字入力ストリームにバッファリング機能を提供することです。基礎となる文字入力ストリーム(in)の文字を独自のバッファー(内蔵キャッシュ文字配列)に読み取り、プログラムはバッファレッドリーダーの読み取りメソッドを呼び出して、バッファ内のバッファーのキャラクターをプログラムに読み込みます。バッファ内の文字が読み取られると、BufferedReaderは、データが読み取られるまでプログラムから読み取るためにバッファーから次のデータブロックを読み取ります。これを行うことの利点は、第一に、読解効率を改善し、次に、ストレージ媒体を開くための接続の数を減らすことです。詳細な理由で、以下に説明するbufferedwriter。重要なメソッドfill()があります。これは、バッファ内のデータがディスクから読み取られるものよりも10倍速く読み取られるたびに、INからデータを入力し、バッファーからのデータを入力するためです。これは効率の非常に恐ろしい改善です。同時に、禁止せずにバッファレッドリーダーのバッファサイズを指定することはできません。結局のところ、一度に読むのに長い時間がかかります。第二に、メモリ価格は比較的高価です。私たちにできることは、その中に合理的なポイントを見つけることです。一般的に、バッファレッドリーダーを作成するときに、それについて心配してバッファのデフォルトサイズを使用する必要はありません。
2。BufferedReaderAPIの紹介:
A:メソッドの構築bufferedreader(Reader in、int SZ)は、指定されたサイズと基礎となる文字入力ストリームに基づいてBufferedReaderを作成します。 BR BufferedReader(Reader in)デフォルトサイズを使用して、基礎となる出力ストリームBのバッファーストリームを作成しますB:一般的な方法void close()このストリームを閉じ、このストリームに関連するすべてのリソースをリリースし、このストリームの位置をマークします。このストリームは、文字を読み取ることができますint read()は単一の文字を読み取り、整数形式で返します。 inの終了が読み取られた場合、それは-1を返します。 int read(char [] cbuf、int off、int len)cbuf off offから始まるcbufでレン文字を読む、長さのlen string readline()read read on long skip(long n)docard n文字
3。ソースコード分析
パッケージcom.chy.io.original.code; Import java.io.ioexception;/***基礎となる文字入力ストリームの文字バッファリングCBアレイを追加します。効率を改善 * @version 1.1、13/11/17 * @authorandychen */public class bufferedreader extends reader {private reader in;プライベートチャーCB []; Private int nchars、NextChar;プライベート静的最終int無効= -2;プライベートスタティックファイナルインマーク= -1; private int markedChar =マークなし; private int readaheadlimit = 0; /*マーク付きの場合にのみ有効> 0*// **次の文字がラインフィードの場合、スキップ*/ private boolean skiplf = false; / **マークが設定されたときのSkiplfフラグ*/ private boolean markedskiplf = false; private static int defaultcharbuffersize = 8192; private static int defaultExpectedLinElength = 80; /***指定されたサイズと基礎となる文字入力ストリームに基づいて、バッファレッドリーダーを作成します。 br */ public bufferedReader(Reader in、int sz){super(in); if(sz <= 0)throw new IllegalargumentException( "Buffer Size <= 0"); this.in = in; cb = new char [sz]; nextchar = nchars = 0; } / ***デフォルトのサイズを使用して、基礎となる出力ストリームのバッファーストリームを作成します* / public bufferedReader(reader in){this(in、defaultcharbufferize); } / **基礎となる文字入力ストリームが閉じているかどうかを検出* / private void sureseopen()はioexception {(in == null)throw new ioException( "stream closhing")をスローします。 } /*** CBに記入します。 */ private void fill()throws ioexception {int dst; if(markedchar <= unsered){/ *no mark */ dst = 0;} else {/ *marked */ int delta = nextchar -markedChar; if(delta> = readaheadlimit){/ * read-ahead制限を過ぎた:nivalidate mark */markedchar = invalidated; readaheadlimit = 0; dst = 0; } else {if(readaheadlimit <= cb.length){ / *現在のバッファーのシャッフル * / system.arraycopy(cb、markedchar、cb、0、delta); MarkedChar = 0; dst = delta;} else { / * read-head limitに対応するためにバッファを再配置します * / char ncb [] = new char [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;}} /***単一の文字を読み、整数として返します。 inの終了が読み取られた場合、それは-1を返します。 */ public int read()throws ioexception {synchronized(lock){surseopen(); for(;;){if(nextchar> = nchars){fill(); if(nextchar> = nchars)return -1;} if(skiplf){skiplf = false; if(cb [nextchar] == '/n'){nextchar ++;継続; }} cb [nextchar ++]; }}} /*** len文字を読み取り、subscript offから始まる長さのレンの文字を読み取ります。ローカルバッファーへの文字。このようにして、バッファリングされたストリームは無害にカスケードされます。 */ 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; } / *** len文字を読み取りcbufから長さのlenからindex off off off off off* / public int read(char cbuf []、int off、int len)throws ioexception {synchronized(lock){seressopen(); if((off <0)||(off> cbuf.length)||(len <0)||((off + len)> cbuf.length)||((off + len)<0)){throw new new indexoutofboundsexcection(); } 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; N同期(lock){sureseopen(); boolean omitlf =無知|| 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; / *必要に応じて残りの '/n'をスキップします */if(obitlf &&(cb [nextchar] == '/n'))nextchar ++; skiplf = false; omitlf = false; Charloop:for(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 = new String(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(defaultExpectedLinelength); s.Append(cb、startchar、i -startchar); }}} / ** * in、 * / public string readline()throws ioexception {return readline(false); } / *** in in* / public long skip(long n)throws ioException {if(n <0l){throw new IllegalargumentException( "Skip Value is Negial");} synchronized(lock){suriseopen();長い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;}} / ** * cbが空であるかどうか、または根底にあるかどうかを判断します。 / * * Newlineをスキップする必要があり、次のCharが読み取られる場合 *がNewlineキャラクターである場合、すぐにスキップしてください。 */ if(skiplf){/ * in.ready()は、ストリームで次の *読み取りがブロックされない場合にのみtrueを返すことに注意してください。 */if(nextchar> = nchars && in.ready()){fill();} if(nextchar <nchars){if(cb [nextchar] == '/n')nextchar ++; skiplf = false;}} return(nextchar <nchars)|| in.Ready();}} / ***このストリームがマークをサポートするかどうかを判断します* / public boolean marksupported(){return true; } /***この時点でこのストリームの位置をマークし、リセットするメソッドが失敗する前に、readaheadlimit文字まで読み取りを許可します。 */ public void mark(int readaheadlimit)throws ioexception {if(readaheadlimit <0){throw new IllegalargumentException( "read-ahead lime <0");}同期(lock){sureseopen(); this.readaheadlimit = readaheadlimit; MarkedChar = NextChar; markedskiplf = skiplf;}} /***最後にマークされた位置をリセットします。つまり、次のキャラクターは、最後にマークされた位置から読まれます。 */ public void reset()throws ioexception {synchronized(lock){surseopen(); if(markedChar <0)Throw new ioException((markedChar == invalidated)? "Mark Invalid": "Stream Not Marked"); NextChar = MarkedChar; skiplf = markedskiplf;}} //このストリームを閉じて、このストリームに関連するすべてのリソースをリリースしますpublic void close()throws ioexception {synchronized(lock){if(in == null)return; in.close(); in = null; cb = null;}}}4。デモンストレーションの例:
パッケージcom.chy.io.original.test;インポートjava.io.bufferedreader; Import java.io.bufferedwriter; import java.io.file.file; import java.io.filewriter; import java.io.io.fileterter; import java.io.io.ioexfferred bufferdwerred fufferfrentberdwerdwerdwrentberdwredwrend bufferdwredwredwredwredwredception {/***ここでのこれらの2つのクラスのテストは比較的簡単です。これはファイル文字ストリームをラップしてファイルコピーを実装することです*興味がある場合は、効率をテストし、怠zyであり、無視できます*/public static void main(string [] args)throws {file resoucefile = newファイル( " file( "e://copyoftest.txt"); bufferedreader br = new bufferedReader(new fileReader(resoucefile)); bufferedwriter bw = new filewriter(targetfile)); char [] cbuf = new char [1024]; int n = 0; -1){bw.write(cbuf、0、n);} //フローを更新して閉じることを忘れないでください。そうしないと、一方でリソースはリリースされず、br.close(); bw.close(); bw.close();}}の場合、データ損失を引き起こす可能性があります。要約:
BufferedReaderおよびBufferedWriterの場合、本質は、基礎となる文字入力および出力ストリームにバッファリング機能を追加し、最初に基礎となるストリームのデータを一度に読み取りまたは書き込み、バッファーで動作させることです。これは効率だけでなく、リソースを節約します。最後に、プログラムでは、効率的な理由で、これらの2つのクラスを、ストリームを保持して直接アップロードするのではなく、それらを直接アップロードするのではなく、それらを飾るためにそれらを飾るためにそれらを飾るためにそれらを飾る必要があります。