2016-04-25 31 views
0

私はデータをフィルタリングするプログラムを書こうとしています。データには27,000行が含まれ、150MB以上です。どのように関数を実装しようとしても、4,300行目の途中で途中で印刷が中止されます。私はデータを印刷せずに(ループ番号を印刷するだけで)ループをテストし、それは完全な27,000行に達します。私はこれが記憶上の問題かもしれないと思っていますが、私はJavaでとても新しいので、どこに問題があるのか​​特に分かりません。現在主張されているのは、line.substringとPrintStreamクラスです。助けてください!Javaのファイルメモリ制限に書き込む?

public static void main(String[] args) { 
    // tries to print output to output.csv in same directory 
    try { 
    PrintStream out = new PrintStream(new FileOutputStream("output.csv")); 
    System.setOut(out); 
    } 
    catch(IOException e1) { 
    System.out.println("Error during reading/writing"); 
    } 

    // read input file 
    File inputFile = new File("my-large-file.txt"); 

    if(!inputFile.canRead()) { 
    System.out.println("Required input file not found; exiting."); 
    System.exit(1); 
    } 

    // doesn't allow me to use scanner without try for some reason 
    try { 
    Scanner input = new Scanner(inputFile); 

    while (input.hasNextLine()) { 
     String line = input.nextLine(); 

     // scan through each line 
     Scanner lineScan = new Scanner(line); 

     // if we find the line that we want to look through 
     if(lineScan.next().startsWith("1")) { 

      // prints the specific data to output 
      String a= line.substring(007, 666);   
      if (!(a== "the-number-that-I-don't-want")) { 
       String current   = line.substring(1, 10); 
       String another   = line.substring(10, 20).replaceAll("\\s+",""); 
       String third   = line.substring(20, 30).replaceAll("\\s +",""); 
       String fourth   = line.substring(40, 50); 
       ... 
       String nth    = line.substring(999, 1000); 


       System.out.print(current + ", "); 
       System.out.print(another + ", "); 
       System.out.print(third + ", "); 
       System.out.print(fourth + ", "); 
       ... 
       System.out.print(nth); 
       System.out.println(); 

      } 
     } 
    } 
    } 
    catch(IOException e) { 
    e.printStackTrace(); 
    } 

}

+0

何のパラメータあなたは時にヒープサイズのために使用されていますあなたはプログラムを実行する?これを実行するには、メモリサイズを上げる必要があります。 http://stackoverflow.com/questions/1565388/increase-heap-size-in-java – ManoDestra

+0

また、この行を次のように記述する必要があります。 '!(" the-number-that-I-don-want-want ".equals(a))' – ManoDestra

+0

@ManoDestra、私はヒープサイズを設定する方法を知らないし、以前にそれについて聞いていない。私は今それを探していますが、デフォルトサイズがjGraspであれば何でも構わないと思いますか?おそらく。そして、あなたの提案に感謝します!私は自分のコードを更新します –

答えて

0

私はそれを理解することができました!正しい方向に私を指差してくれてありがとう。

私のプログラムの問題は、あまりにも多くのメモリをメモリに格納していたことでした。私はファイル内に各行を格納しておき、行をスキャンしたり、文字列を格納したり、文字列を連結したりする別のスキャナを格納していました。

文字列の代わりにStringBufferが使用されます。ここで

が意図したとおりに機能するようになりました私の改訂ソリューションは、ファイルやフィルタを通るである:

public static void main(String[] args) throws IOException { 
    FileInputStream inputStream = null; 
    Scanner sc = null; 
    try { 
    PrintStream out = new PrintStream(new FileOutputStream("output.csv")); 
    System.setOut(out); 
    } 
    catch(IOException e1) { 
    System.out.println("Error during reading/writing"); 
    } 
    try { 
     inputStream = new FileInputStream("my-large-file.txt"); 
     sc = new Scanner(inputStream, "UTF-8"); 
     while (sc.hasNextLine()) { 
     String line = sc.nextLine(); 

     // note the specific indecies of the substring are random nums, and does not affect the program. They could be anything. 
     if (!line.startsWith("the-number-that-I-don't-want"))) { 
      String filter2 = line.substring(55, 66);   
      if (!(filter2.equals("another-string-to-filter-out"))) { 
       StringBuffer current  = new StringBuffer(line.substring(1, 10)); 
       StringBuffer another  = new StringBuffer(line.substring(10, 20).replaceAll("\\s+","")); 
       StringBuffer third  = new StringBuffer(line.substring(22, 37).replaceAll("\\s +","")); 
       StringBuffer fourth  = new StringBuffer(line.substring(37, 56)); 

       ... 
       StringBuffer nth   = new StringBuffer(line.substring(999, 1000)); 

       System.out.println(currentS + ", " + firstName + ", " + lastName + ", " + birthday + ", " + distributedAmt + ", " +awardYear + ", " + transactionNum + ", " + disbursementDate + ", " + efc + ", " + percentEligUsed + ", " + grantType); 
      } 
     } 
    } 

    if (sc.ioException() != null) { 
     throw sc.ioException(); 
    } 
    } finally { 
    if (inputStream != null) { 
     inputStream.close(); 
    } 
    if (sc != null) { 
     sc.close(); 
    } 

    }                    
} 

このリンクは、多くのことを私を助け:http://www.baeldung.com/java-read-lines-large-file

0

String.substringは、有効なインデックスを必要とします。文字列の比較にはequalsが使用されます。

if (line.length() >= 666) { // Or even 1000 
     String a = line.substring(007, 666);   
     if (!a.equals("the-number-that-I-don't-want")) { 
     ... 
    } 

次に、開いているすべてを閉じる必要があります。 lineScan、特にinputである。

この場合、BufferedReaderはトークンを分割するScannerよりも直感的です。 BufferedReaderはよりシンプルであり、おそらく高速です。

+0

私はBufferedReaderを試してみましたが、これまでこれを解決していませんでした。私はあなたと@ ManoDestraの提案に従って、.equalsを修正しました、ありがとう!私は行の長さについての情報を含んでいませんでしたが、毎回固定長です。私はハッキングを続け、BufferedReaderがそれを解決するかどうかを知らせます –

関連する問題