1。概要
このチュートリアルでは、Javaで大きなファイルを効率的に読み取る方法を示します。 Java-基本に戻ります。
2。メモリを読んでください
ファイル行を読み取る標準的な方法は、メモリで読むことです。 GuavaとApacheCommonsioの両方が、次のようにファイル行をすばやく読み取る方法を提供します。
Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));
この方法の問題は、ファイルのすべての行がメモリに保存され、ファイルが十分に大きい場合、プログラムはすぐにOutMemoryError例外をスローすることです。
例:約1gのファイルを読む:
@testpublic void disdusingguava_wheniteratingafile_thenworks()throws ioexception {string path = ... files.readlines(new file(path)、charsets.utf_8);}この方法は、最初に少量のメモリしか占めていません:(約0MBのメモリを消費します)
[メイン]情報org.baeldung.java.corejavaiounittest-合計メモリ:128 MB [メイン]情報org.baeldung.java.corejavaiounittest-フリーメモリ:116 MB
ただし、すべてのファイルがメモリに読み取られると、最終的に表示できます(約2GBのメモリが消費されます):
[メイン]情報org.baeldung.java.corejavaiounittest-合計メモリ:2666 MB [メイン]情報org.baeldung.java.corejavaiounittest-無料メモリ:490 mb
これは、このプロセスが約2.1GBのメモリを消費することを意味します - 理由は単純です。これで、ファイルのすべての行がメモリに保存されます。
ファイルのすべてのコンテンツをメモリに配置すると、使用可能なメモリがすぐに使い果たされます。実際に利用可能なメモリがどれほど大きくても、これは明らかです。
さらに、通常、ファイルのすべての行を一度にメモリに入れる必要はありません。代わりに、ファイルの各行を通過してから対応する処理を実行し、処理後に捨てるだけです。ですから、それがまさに私たちがやろうとしていることです - すべての行をメモリに置くのではなく、行を繰り返します。
3。ファイルストリーム
次に、このソリューションを見てみましょう - java.util.scannerクラスを使用して、ファイルの内容をスキャンし、行ごとに継続的に読み取ります。
fileInputStream inputstream = null; scanner sc = null; try {inputstream = new fileinputStream(path); sc = new Scanner(inputstream、 "utf-8"); while(sc.hasnextline()){string line = sc.nextline(); // system.out.println(line); } //スキャナーは例外を抑制することに注意してください(sc.ioexception()!= null){throw sc.ioexception(); }}最後に{if(inputstream!= null){inputstream.close(); } if(sc!= null){sc.close(); }}このソリューションは、ファイル内のすべての行を通過します。これにより、各行を参照せずに各行を処理できます。とにかく、それらはメモリに保管されていませんでした:(約150MBのメモリが消費されました)
[メイン] infoorg.baeldung.java.corejavaiounittest-totalmemory:763MB
[メイン] infoorg.baeldung.java.corejavaiounittest-freememory:605mb
4。ApacheCommonsioストリーム
ライブラリが提供するカスタムラインターターを使用して、Commonsioライブラリを使用して実装することもできます。
lineiterator it = fileutils.lineTerator(thefile、 "utf-8"); try {while(it.hasnext()){string line = it.nextline(); //ラインで何かをします}}最後に{lineiterator.closequetly(it);}ファイル全体がメモリに保存されていないため、これはかなり保守的なメモリ消費につながります:(約150MBのメモリが消費されます)
[Main] Infoo.B.Java.CoreJavaioIntegrationTest-TotalMemory:752MB
[Main] Infoo.B.Java.CoreJavaioIntegrationTest-Freememory:564MB
5。結論
この短い記事では、メモリを繰り返し読んだり、繰り返したりすることなく大きなファイルを処理する方法について説明します。これは、大きなファイルを処理するための便利なソリューションを提供します。
これらの例はすべて実装されており、私のGitHubプロジェクトで利用可能なコードスニペット - これはEclipseベースのプロジェクトであるため、簡単にインポートして実行する必要があります。
上記は、この記事のすべての内容が、Javaの大規模なファイルの効率的な読み取りに関するコンテンツです。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!