BufferedReader
とFileReader
の具体的な違いを知りたい。
BufferedReader
はFileReader
よりもはるかに効率的であることは知っていますが、その理由を(具体的かつ詳細に)誰か説明していただけますか?ありがとう。
簡単な方法で:
FileReaderクラスは、ファイルから文字を読み取るための一般的なツールです。 BufferedReaderクラスは、FileReaderなどのリーダーをラップして、入力をバッファリングし、効率を向上させることができます。したがって、FileReaderオブジェクトをBufferedReaderコンストラクターに渡すことで、一方を他方では使用せず、両方を同時に使用します。
非常に詳細
FileReaderは、ディスクファイルからの文字データの入力に使用されます。入力ファイルは、通常のASCII、文字テキストファイルごとに1バイトにすることができます。 Readerストリームは、文字をディスクファイル形式から内部文字形式に自動的に変換します。入力ファイルの文字は、UTF形式でサポートされている他のアルファベットの文字である場合があります。この場合、文字ごとに最大3バイトが使用されます。この場合、ファイルの文字もchar形式に変換されます。
出力と同様に、効率を改善するためにバッファを使用することをお勧めします。これにはBufferedReaderを使用します。これは、キーボード入力に使用してきたのと同じクラスです。これらの行はおなじみのはずです:
BufferedReader stdin =
new BufferedReader(new InputStreamReader( System.in ));
これらの行はBufferedReaderを作成しますが、ファイルではなくキーボードからの入力ストリームに接続します。
ソース: http://www.oopweb.com/Java/Documents/JavaNotes/Volume/chap84/ch84_3.html
まず、Javaの「ストリーミング」を理解する必要があります。これは、Javaのすべての「リーダー」がこの概念に基づいているためです。
ファイルストリーミング
ファイルストリーミングは、JavaのFileInputStreamオブジェクトによって実行されます。
// it reads a byte at a time and stores into the 'byt' variable
int byt;
while((byt = fileInputStream.read()) != -1) {
fileOutputStream.write(byt);
}
このオブジェクトは、実際には一度に1バイト(8ビット)を読み取り、指定されたファイルに書き込みます。
実用的な便利なアプリケーションは、画像や音声ファイルなどの生のバイナリ/データファイルを操作することです(音声ファイルにはFileInputStreamの代わりにAudioInputStreamを使用します)。一方、テキストファイルの場合、一度に1バイトずつループするため、非常に不便で遅くなります。その後、処理を行い、処理されたバイトを保存するのは面倒で時間がかかります。
また、テキストファイルの文字セットを指定する必要があります。つまり、文字がLatinまたは中国語にある場合など。それ以外の場合、プログラムは一度に8ビットをデコードおよびエンコードし、画面に奇妙な文字が出力されたり、出力ファイルに書き込まれたりします(char 1バイト長)。
ファイルの読み取り
これは、包括的な文字セットのサポート(つまり、前述のように文字セットを定義する必要はありません)を使用した「ファイルストリーミング」を表現するための素晴らしい方法です。
FileReaderクラスは、テキストファイルを処理するために特別に設計されています。前に見たように、ファイルストリーミングは生のバイナリデータを処理するのに最適ですが、テキストのために、それほど効率的ではありません。
そのため、Java-dudesはFileReaderクラスを追加して、テキストファイルを具体的に処理しました。一度に2バイト(または4バイト、文字セットによって異なります)を読み取ります。前のFileInputStreamを大幅に上回る改善!!
ストリーミング操作は次のようになります
int c;
while ( (c = fileReader.read()) != -1) { // some logic }
両方のクラスは、入力ファイルから取得した値を格納するために整数変数を使用することに注意してください(したがって、すべての文字はフェッチ中に整数に変換され、格納中に文字に戻ります)。
ここでの唯一の利点は、このクラスがテキストファイルを処理するため、テキストファイルの文字セットと他のいくつかのプロパティを指定する必要がないことです。基本的に、ほとんどのテキストファイル処理の場合に、すぐに使用できるソリューションを提供します。また、国際化とローカライズもサポートしています。
しかし、やはり遅すぎます(一度に2バイトを読み取り、ループすることを想像してください!)。
ストリームのバッファリング
1バイトまたは2を超える連続ループの問題に取り組むために、Javaの男は別の素晴らしい機能を追加しました。 "処理前にデータのバッファを作成します。"
ユーザーがYouTubeでビデオをストリーミングするとき、この概念はほとんど同じです。完璧なビデオ視聴体験を提供するために、ビデオは再生前にバッファリングされます。 (つまり、ブラウザはビデオ全体が事前にバッファリングされるまでバッファリングを続けます。)同じテクニックがBufferedReaderクラスによって使用されます。
BufferedReaderオブジェクトは、すべてを含む入力としてFileReaderオブジェクトを取ります読み取る必要があるテキストファイルに関する必要な情報。 (ファイルパスや文字セットなど。)
BufferedReader br = new BufferedReader( new FileReader("example.txt") );
BufferedReaderオブジェクトに「読み取り」命令が与えられると、FileReaderファイルからデータを読み取るオブジェクト。命令が与えられると、FileReaderオブジェクトは一度に2(または4)バイトを読み取り、データをBufferedReaderそして、リーダーは '\ n'または '\ r\n'(行末記号)に達するまでそれを続けます。行がバッファリングされると、リーダーは次の行をバッファリングする命令が与えられるまで辛抱強く待機します。
一方、BufferReaderオブジェクトは、「Buffer」と呼ばれる特別なメモリ場所(RAM上)を作成し、FileReaderオブジェクト。
// this variable points to the buffered line
String line;
// Keep buffering the lines and print it.
while ((line = br.readLine()) != null) {
printWriter.println(line);
}
ここで、一度に2バイトを読み取る代わりに、行全体がフェッチされ、RAMのどこかに格納されます。データの処理が完了したら、行全体を元に戻すことができます。そのため、プロセスは1回に2バイトを実行するよりもずっと速く実行されます。
しかし、もう一度、なぜFileReaderオブジェクトをBufferReaderに渡す必要があるのでしょうか? 「このファイルをバッファする」と言えば、BufferReaderが残りを処理しますか?それは甘くないでしょうか?
さて、BufferReaderクラスは、バッファの作成方法と着信データの格納方法のみを知っている方法で作成されます。データの送信元のオブジェクトは重要ではありません。
つまり、FileReaderオブジェクトを入力として提供すると、InputStreamReaderをオブジェクトとして提供した場合と同じように、ファイルをバッファリングします。新しいラインシンボルに到達するまで、ターミナル/コンソール入力データをバッファします。といった、
// Object that reads console inputs
InputStreamReader console = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(console);
System.out.println(br.readLine());
このように、同じBufferReaderクラス(テキストファイル、コンソール、プリンター、ネットワークデータなど)で複数のストリームを読み取る(またはバッファーする)ことができます。覚えておく必要があるのは、
bufferedReader.readLine();
バッファリングしたものをすべて印刷します。
BufferedReaderにはReaderが必要です。FileReaderの1つは、Readerから派生するInputStreamReaderから派生します。