次の 2 つのバッファリング アプローチの違い (ある場合) は何ですか?
Reader r1 = new BufferedReader(new InputStreamReader(in, "UTF-8"), bufferSize);
Reader r2 = new InputStreamReader(new BufferedInputStream(in, bufferSize), "UTF-8");
次の 2 つのバッファリング アプローチの違い (ある場合) は何ですか?
Reader r1 = new BufferedReader(new InputStreamReader(in, "UTF-8"), bufferSize);
Reader r2 = new InputStreamReader(new BufferedInputStream(in, bufferSize), "UTF-8");
r1
より効率的です。自体にはInputStreamReader
大きなバッファがありません。はBufferedReader
、 よりも大きなバッファを持つように設定できますInputStreamReader
。InputStreamReader
インr2
はボトルネックとして機能します。
要するに、ボトルではなく、じょうごを通してデータを読み取る必要があります。
更新: ここに小さなベンチマーク プログラムがあります。コピーして貼り付けて実行するだけです。ファイルを準備する必要はありません。
package com.stackoverflow.q3459127;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
public class Test {
public static void main(String... args) throws Exception {
// Init.
int bufferSize = 10240; // 10KB.
int fileSize = 100 * 1024 * 1024; // 100MB.
File file = new File("/temp.txt");
// Create file (it's also a good JVM warmup).
System.out.print("Creating file .. ");
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(file));
for (int i = 0; i < fileSize; i++) {
writer.write("0");
}
System.out.printf("finished, file size: %d MB.%n", file.length() / 1024 / 1024);
} finally {
if (writer != null) try { writer.close(); } catch (IOException ignore) {}
}
// Read through funnel.
System.out.print("Reading through funnel .. ");
Reader r1 = null;
try {
r1 = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"), bufferSize);
long st = System.nanoTime();
for (int data; (data = r1.read()) > -1;);
long et = System.nanoTime();
System.out.printf("finished in %d ms.%n", (et - st) / 1000000);
} finally {
if (r1 != null) try { r1.close(); } catch (IOException ignore) {}
}
// Read through bottle.
System.out.print("Reading through bottle .. ");
Reader r2 = null;
try {
r2 = new InputStreamReader(new BufferedInputStream(new FileInputStream(file), bufferSize), "UTF-8");
long st = System.nanoTime();
for (int data; (data = r2.read()) > -1;);
long et = System.nanoTime();
System.out.printf("finished in %d ms.%n", (et - st) / 1000000);
} finally {
if (r2 != null) try { r2.close(); } catch (IOException ignore) {}
}
// Cleanup.
if (!file.delete()) System.err.printf("Oops, failed to delete %s. Cleanup yourself.%n", file.getAbsolutePath());
}
}
Seagate Momentus 7200.3ハードディスクを搭載した Latitude E5500 での結果:
ファイルの作成が完了しました。ファイル サイズ: 99 MB。 じょうごを介した読み取り.. 1593 ミリ秒で終了しました。 ボトルの読み取り.. 7760 ミリ秒で終了しました。
r1
BufferedReader
サポートされているreadLine
メソッドとして行ベースのストリームを読み取る場合にも便利です。コンテンツを char 配列バッファーまたは chars に 1 つずつ読み取る必要はありません。ただし、変数に対して明示的にその型にキャストr1
するか、その型を使用する必要があります。BufferedReader
私はよく次のコード スニペットを使用します。
BufferedReader br = ...
String line;
while((line=br.readLine())!=null) {
//process line
}