2,000 万行のテキストを含む大きなテキスト ファイルがあります。次のプログラムを使用してファイルを読み取ると、問題なく動作し、実際、メモリの問題なしで、より大きなファイルを読み取ることができます。
public static void main(String[] args) throws IOException {
File tempFile = new File("temp.dat");
String tempLine = null;
BufferedReader br = null;
int lineCount = 0;
try {
br = new BufferedReader(new FileReader(tempFile));
while ((tempLine = br.readLine()) != null) {
lineCount += 1;
}
} catch (Exception e) {
System.out.println("br error: " +e.getMessage());
} finally {
br.close();
System.out.println(lineCount + " lines read from file");
}
}
ただし、このファイルを読み取る前にいくつかのレコードを追加する必要がある場合、BufferedReader は大量のメモリを消費します (これを監視するために Windows タスク マネージャーを使用しましたが、あまり科学的ではありませんが、問題を示しています)。修正されたプログラムを以下に示します。最初のプログラムと同じですが、最初に単一のレコードをファイルに追加しています。
public static void main(String[] args) throws IOException {
File tempFile = new File("temp.dat");
PrintWriter pw = null;
try {
pw = new PrintWriter(new BufferedWriter(new FileWriter(tempFile, true)));
pw.println(" ");
} catch (Exception e) {
System.out.println("pw error: " + e.getMessage());
} finally {
pw.close();
}
String tempLine = null;
BufferedReader br = null;
int lineCount = 0;
try {
br = new BufferedReader(new FileReader(tempFile));
while ((tempLine = br.readLine()) != null) {
lineCount += 1;
}
} catch (Exception e) {
System.out.println("br error: " +e.getMessage());
} finally {
br.close();
System.out.println(lineCount + " lines read from file");
}
}
Windows タスク マネージャーのスクリーンショット。2 番目のバージョンのプログラムを実行したときの行の大きな隆起がメモリ消費量を示しています。
そのため、メモリ不足になることなくこのファイルを読み取ることができました。しかし、5,000 万を超えるレコードを含むはるかに大きなファイルがあり、それらに対してこのプログラムを実行すると、メモリ不足の例外が発生しますか? プログラムの最初のバージョンはどのようなサイズのファイルでも問題なく動作するのに、2 番目のプログラムは動作が大きく異なり、失敗に終わる理由を誰か説明できますか? 私はWindows 7で次を実行しています:
Java バージョン "1.7.0_05"
Java(TM) SE ランタイム環境 (ビルド 1.7.0_05-b05)
Java HotSpot(TM) クライアント VM (ビルド 23.1-b03、混合モード、共有)