• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:大容量のテキストファイルの内容を解析について)

大容量テキストファイルの内容解析について

このQ&Aのポイント
  • 10000行1GBほどの大容量のテキストファイルの内容を解析しようとしています。メモリ不足を解消するため、20行ごとに処理を行う方法を検討しています。
  • 現在、全行を1行ごとにArrayListに格納してからキーワードのチェックを行っていますが、途中でOutOfMemoryになる問題が発生しています。
  • そのため、20行ごとにデータを読み込み、処理を行う方法を検討しています。皆さんはどのような手法を使用しているのか教えていただけると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

そもそもListに入れる必要が無いと思います。 ・2行目は覚えておく ・"区切りキーワード"を見つけるまで、1行ずつキーワードが含まれているかチェックする。 ・"区切りキーワード"を見つけるか、最後まで読み込んだ時に、直前のブロックにキーワードが 含まれていたら、覚えておいた2行目を出力する。 String secondLine = "2行目が無かった"; String line = br.readLine(); while (line != null) { // 全体が終わるまでループ it cnt = 1; // 処理行数(ブロック内の) boolean isFound = false; // キーワード発見フラグ while (line != null) { // 全体が終わるまでループ(区切りキーワードが見つかったらbreak)) if (line.contains(Sep)) { break; // 区切りキーワード発見 } if (cnt == 2) { secondLine = line; // 出力用の2行目を退避 } if (!isFound && line.contains(keyword)) { isFound = true; // キーワード発見 } line = br.readLine(); // 次行読み込み cnt++; } if (isFound) { System.out,println(secondLine); secondLine = "2行目が無かった"; } }

sunikku
質問者

お礼

なるほど!Listに入れなくてはいけないというのは自分の固定観念でした! たしかにそもそもListに入れる必要はなさそうですね! ありがとうございます。 ベストアンサーとして選ばさせていただきます。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

これ, 「データの塊」ごとに処理すればいいだけじゃないでしょうか? もしそうなら 「1つの『データの塊』を読み込むメソッド」 を作るのが簡単だと思う.

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.4

具体的な例を出したほうが、誤解などが少なくなると思います

noname#147388
noname#147388
回答No.3

ぱっと考えつくのは BufferedReader in = getReader(); List<String> lines = new ArrayList<String>(); String line; System.out.println("----------------------"); while (in.ready()) { line = in.readLine(); lines.add(line); if (lines.size() == 3) { for (String l : lines) { if (l.indexOf("15") >= 0) { System.out.println(lines.get(1)); } } lines.clear(); } } System.out.println("----------------------"); だがこれも OutOfMemory でるから。 http://java.sun.com/javase/ja/6/docs/ja/api/java/io/RandomAccessFile.html 利用したら? 2GBの壁にきをつければ。。。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.2

20行ワンセットが約束されてるなら。 grepかfindで、キーワードを含む行番号を取得して考える。

sunikku
質問者

補足

すみません。言葉不足でした。 20行が必ずワンセットになっているとは限りません。ただ、30行の中には必ず収まっていることと、 データとデータの塊の境目に必ず”区切りキーワード”がくることがわかっています。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そりゃぁ「最初の20行を読み込み、処理をし、次の20行を読み込み処理をする」のは可能です. とりあえず「最初の 20行を読み込む」ところだけ書いてみてください.

sunikku
質問者

補足

補足します。実際のデータは必ず20行が約束されているわけではありませんが、30行までにはひとつのデータの塊が収まることがわかっています。そして、データとデータの境には”区切りキーワード”が必ずあることがわかっています。 そこで以下のように最初の30行を”区切りキーワード”が来るまでArrayListに格納し、処理をするところのプログラムです。 ここから先が不明なのは 1.前回読み込んだ行までを覚えて、 2.その行をスタート位置とし、 3.そこから次の30行を読み、同じ処理を繰り返す。 の部分です・・・・。 public static void main(String[] args){ ArrayList<String> copy=new ArrayList<String>();//1行ずつ格納 String Sep = "区切りキーワード";//30行以内には必ず1回はこの区切りキーワードが来ます。 try { br = new BufferedReader(new InputStreamReader             (new FileInputStream("C:\\sample\test.txt"), "Shift_JIS")); while(i<30){  //”区切りキーワードが来るまでループ” line= br.readLine(); copy.add(i, line); i++; if(line.contains(Sep)){ break; } }      for(int k=0;k<copy.size();k++){ //Arraylistに収めた中で処理をする(キーワード検索) if(copy.get(k).contains(" キーワード ")){            //キーワードが見つかったときに、ここに処理を書く。 } }