2016-07-12 4 views
-2

JAVAでより大きなサイズのファイルを読み込む際に問題があります。私は読むために使用されるファイルは、私がBufferedReaderのスキャナLineNumberReaderすべての読み取りに失敗し、のOutOfMemoryErrorにつながるを使用してファイルを読み込むために使用されるので、750メガバイトのサイズを有しています。テキストファイルの指定された行数を読み取る方法は?

はるかに大きいサイズのファイルを簡単に読み取る方法はありますか?いくつかの行をスキップして行をスキップして特定の行を読み取る方法はありますか?

私は、ファイルの読み取りに使用コード:私は2000に1001からの行数を読み取るように思うなら、私はそれらを読むことができるか、

:たとえば

FileInputStream inputStream = null; 
Scanner sc = null; 
try 
{ 
    inputStream = new FileInputStream(path); 
    sc = new Scanner(inputStream, "UTF-8"); 
    while (sc.hasNextLine()) 
    { 
      String line = sc.nextLine(); 
    }  
    if (sc.ioException() != null) 
    { 
     throw sc.ioException(); 
    } 
} 
finally 
{ 
    inputStream.close(); 
    sc.close(); 
} 

をそのより大きなサイズのファイルからの特定の行。

ありがとうございます。

+0

['RandomAccessFile'](https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html) –

+0

を読みながら、変数' int line'を更新し続けます。あなたが(0ベースのものか1ベースのものが好きかに応じて)その行を読み込んだ後に(または前に)増加します。変数が1001から2000の範囲にある間、あなたはその行で何かをします。そうでなければそれを捨てる。 –

+0

ファイルをどのように処理しますか? 1行ずつ?固定または可変サイズのブロックでは? 1回のパスでファイルを読み込み、レコードを読み込み、それらのすべてをメモリに保存しないで処理することができます。 –

答えて

0

問題は、行の終わりを知ることです。それは、そのファイルを調べなければ、単純には不可能です。そのような機能はありません特定の行番号で読むことができます。 の特定のバイト位置について質問した場合、回答はjava.io.RandomAccessFileとなります。

だから、あなたは2つのオプションがあります。あなたがあなたに到達するまで、特定の行番号で読ん新しいをBufferedReader(および基礎となるストリーム)を作成し、すべての行をスキップするたびに

  1. を希望のもの。その名前が示すように、BufferedReaderは入力ソースを4096文字(8192バイト)のチャンクでバッファします。ほとんどの場合、これで十分です。
  2. 最初のオプションがあまりにも遅い(1秒に何回も読みなければならないなど)場合は、ファイルのインデックスを作成します。その意味は次のとおりです。新しいRandomAccessFileを作成し、すべての改行を検索し、バイトオフセットを覚えておいてください。特定の行を読み込むたびに、バイトオフセットを逆に調べるだけです。インデックスは行番号で、intの配列を使用できます。これは、ルックアップのためにO(1)という時間の複雑さをもたらす。ただし、は注意してください。:インデックス作成後にファイルが変更されると、すべてのバイトオフセットが無効になります。したがって、ファイルを再度索引付けする必要があります。

編集:2番目のオプションは、ファイルだけ空行が含まれていないことが必要です。その場合、lookup-arrayはOutOfMemoryErrorをトリガーします。各Java intは4バイト必要です。ファイルに書き込まれた改行に少なくとも1バイトが必要であると仮定すると、係数は4になります。したがって、750 MBの大きなファイルを索引付けする場合、配列には少なくとも4 * 750 MB = 3 GBが必要です。したがって、コマンドラインオプション-Xmxを使用してJVMヒープを拡大する必要があります。

第二編集:ファイルが一つだけの行が含まれている場合piet.tは、上述したように、あなたはまた、コマンドラインオプション-XmxでJVMのヒープを拡大する必要があります。

関連する問題