私は非常に大きなファイル(〜2ギガバイト)を読み取るしようとしています。コンテンツは、文章(私はに基づいてそれらを分割したい「」)に連続した文字列です。私がしようとどのように関係なく、私はOutOfMemoryErrorが発生してしまいます。
BufferedReader in = new BufferedReader(new FileReader("a.txt"));
String read = null;
int i = 0;
while((read = in.readLine())!=null) {
String[] splitted = read.split("\\.");
for (String part: splitted) {
i+=1;
users.add(new User(i,part));
repository.saveAll(users);
}
}
また、
inputStream = new FileInputStream(path);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
// System.out.println(line);
}
// note that Scanner suppresses exceptions
if (sc.ioException() != null) {
throw sc.ioException();
}
(10ワードの後に完全に停止して、ランダムな言葉で構成)ファイルの内容:
fmfbqi .xcdqnjqln kvjhw pexrbunnr cgvrqlr fpaczdegnb puqzjdbp gcfxne jawml aaiwwmo ugzoxn .opjc fmfbqi .xcdqnjqln kvjhw pexrbunnr cgvrqlr fpaczdegnb puqzjdbp gcfxne jawml aaiwwmo ugzoxn .opjc (so on)
助けてください!
だから、何よりもまず、あなたの質問にコメントをもとに、ヨアヒム・ザウアーが述べたように:
何改行が存在しない場合、単一の行、従って唯一の行数があります。
だからあなたのユースケースは、最高の状態で、故障しています。
その過去レッツ移動、多分そこに改行文字があると仮定-と仮定し、いっそのか、.
上の文字はあなただ分割が改行psudeo置換であることを意図しています。
Scanner
他の人がありますが、ここでは悪いアプローチではありません。あなたが提供しているのでScanner
、それを継続することができますが、あなたはあなたが周りにラップしているようにしたいですBufferedReader
。あなたは明らかに多くのメモリを持っていない、とBufferedReader
によってバッファとして、ファイルの「チャンク」を読んで、あなたのすることができますBufferedReader
の機能を利用しながら、Scanner
完全にバッファリングが起こっていることを、発信者としてのあなたに不明瞭に:
Scanner sc = new Scanner(new BufferedReader(new FileReader(new File("a.txt")), 10*1024));
これは基本的に何をしているか、させて頂いておりScanner
ますが、期待どおりの機能をしていますが、一度に10メガバイトをバッファリングすることができ、あなたのメモリフットプリントを最小限に抑えます。さて、あなただけの呼び出しを保ちます
sc.useDelimiter("\\.");
for(int i = 0; sc.hasNext(); i++) {
String psudeoLine = sc.next();
//store line 'i' in your database for this psudeo-line
//DO NOT store psudeoLine anywhere else - you don't have memory for it
}
あなたが十分なメモリを持っていないので、明確な反復処理するもの(再反復は)それを読んだ後、あなたのJVMのheapspace内のファイルのどの部分を格納しないです。それを読んで、あなたがそれを必要とどのようにそれを使用し、それはJVMのガベージコレクションの対象としてマークすることができます。あなたのケースでは、あなたはあなたが、psudeoラインを読んで、それをデータベースに格納し、それを破棄したいので、データベースにpsudeoラインを保存したい言及します。
そこなあなたのJVM引数を設定するなど、ここで指摘して他のものは、ですが、ちょうどあなたのJVMのメモリを高く設定することがあまりにも悪い考えですので、私もそれを言及することを躊躇 - 別のブルートフォースアプローチ。そこの高いあなたのJVMのメモリ最大ヒープサイズを設定すると何も間違っている、しかし、あなたはまだソフトウェアの書き方を学習している場合は、メモリ管理を学ぶことは良いです。あなたがプロの開発に入る際には、後で少ないトラブルに巻き込まれるだろう。
また、私が述べたScanner
とBufferedReader
、あなたは、あなたの質問にそれを述べたので、私はチェックアウトだと思う)(java.nio.file.Path.linesを deHaarが指し示すても良いアイデアであると。これは基本的にそれはまだ唯一の能力のない時には1行が何をあなたにしている「分割」に変更しないことを警告して、私は明示的にレイアウトされたコードと同じことを行います。テキストファイルは、その中の1つのラインを持っているのであれば、これはまだあなたの問題を引き起こしますし、あなたはまだラインを断片化するスキャナのようなものが必要になります。