2016-04-19 5 views
2

を読み込み、 -
で始まるコメントを削除したいのですが、私はその特定の行を削除することができます私はコードとコメントを同じ行に書いているので、 "\ n--"をしている)。
私はjarファイルに私のプログラムをエクスポートし、それは私のデスクトップで正常に動作しますが、私は私のプログラムで

のjava -Xmx256m -jar MYJARを試してみても、別のコンピュータ(別のPLSQLファイルの読み込み)で、それは私のJavaヒープ領域のエラーを与えます

の.jarエラー:

Exception in thread "main" java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58) 

Caused by: java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Unknown Source) 
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source) 
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source) 
    at java.lang.AbstractStringBuilder.append(Unknown Source) 
    at java.lang.StringBuffer.append(Unknown Source) 
    at ParserDB.ScriptNoComment(ParserDB.java:142) 
    at ParserDB.GetTheName(ParserDB.java:54) 
    at Rapport.SearchCcInDB(Rapport.java:189) 
    at Rapport.listDB(Rapport.java:77) 
    at Rapport.main(Rapport.java:472) 
    ... 5 more 

私のコードは次のとおりです。

public static String ScriptNoComment(String fileName){ 
    String result = null ;  
    try{ 
     FileInputStream fstream = new FileInputStream(fileName); 
     DataInputStream in = new DataInputStream(fstream); 
     BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
     StringBuffer strOut = new StringBuffer(); 
     StringBuilder Out = new StringBuilder(); 
     String strLine; 

     while ((strLine = br.readLine()) != null) { 

      if(strLine.contains("--")){ 
       strLine = strLine.replaceAll("--","\n--"); 
      } 
      strOut.append(strLine+"\n"); 
     } 

     in.close(); 
     //delete comment 
     String[] lines = strOut.toString().split("\\n"); 
     for(String s: lines){ 
      if(s.contains("--")){ 
       s=""; 
      } 
      Out.append(s+"\n"); 
     } 

     result = Out.toString(); 
     result = result.toUpperCase();  
     result = result.replaceAll("\"", ""); 
     result = result.replaceAll("\\r\\n|\\r|\\n", " "); 
     result = result.replaceAll("\\s+", " "); 

     }catch (Exception e){   
     System.err.println("Error: " + e.getMessage()); 
     } 

    return result ; 

} 

は、事前に、感謝を私のコードを最適化するために、とにかくそこにある

EDIT
1 - 私はコマンドを使用して、他のコンピュータにヒープサイズをチェックする) :

のjava -XX: + PrintFlagsFinal -version | FINDSTR/I "HEAPSIZE PermSizeをThreadStackSizeは"

結果であった:分:16MとMAXSIZE:256M のではずのJava -jarテープ:-Xmx512m代わり-Xms256m

2-) 私は(単にテストのために)stringbuilderとすべてのreplaceAllを削除しましたが、私のファイルが大きすぎるために同じエラーが発生しました。

ので、私がやったことだけ例えば50の最初の行を読んで、これだけ50行

に私の方法を適用する(ラインに応じて)私が読んでいる各ファイルの行数をカウントしてみることです

strLine = strLine.replaceAll("--","\n--"); 

、その後、あなたは文字列ビルダに[文字列バッファに書いている:あなたの答えあなたが使用している

+0

多分ヒープスペースを増やすことはできますか?例えば-Xmx2g。 –

+0

Streamアプローチを使います。テキストが大きければ、各操作は 'new String()'を割り当てるため、多くのメモリを消費します。ファイルを読むときに困っている場合は、正規表現操作でもっと大きな問題になります。 – gaborsch

+2

このプログラムは複雑です。最後に、入力を含むStringBuffer、同じ内容の文字列配列、およびコメント以外のすべてを含むStringBuilderがあります。それは3倍のメモリ要件です。代わりに、ファイルを行単位で読み込み、行にコメント(または内容)が含まれているかどうかを確認し、存在する場合は省略/省略することができます。また、ライン上の置換えを行うこともできますので、結果には不要です。そうすることで、あなたのメモリ要件は大幅に削減されます。 –

答えて

1

は、Java 8を持っている場合は、それらを

public static String scriptNoComment(String fileName) { 

    Path filePath = Paths.get(fileName); 
    try (Stream<String> stream = Files.lines(filePath)) { 

    List<String> linesWithNoComments = new ArrayList<String>(); 

    stream.forEach(line -> { 

     if (line.startsWith("--")) { 
     return; 
     } 

     String currentLine = line; 

     int commentStartIndex = line.indexOf("--"); 
     if (commentStartIndex != -1) { 
     currentLine = line.substring(0, commentStartIndex); 
     } 

     currentLine = currentLine.toUpperCase(); 
     currentLine = currentLine.replaceAll("\"", ""); 
     currentLine = currentLine.replaceAll("\\r\\n|\\r|\\n", " "); 
     currentLine = currentLine.replaceAll("\\s+", " ").trim(); 

     if (currentLine.isEmpty()) { 
     return; 
     } 

     linesWithNoComments.add(currentLine); 

    }); 

    return String.join("\n", linesWithNoComments); 

    } catch (IOException e) { 
    e.printStackTrace(System.out); 
    return ""; 
    } 
} 

を処理するなど、Java 8は、あなたが達成するためにはApache StringUtils::joinFileUtils::LineIteratorを使用することができますオプションでない場合は、行のインライン編集のために、このコードを試すことができます同じ結果。これが問題を解決することを願っています。

EDIT

私が処理ラインの特定の数(数は完全にランダムに選ばれた)後にファイルに書き込みを追加Nicolas Filottoの提案を以下に示します。私は両方のメソッドをテストし、最初のものはヒープサイズに近いサイズのファイルで失敗します(文字列内の行の結合にはOPコードと同じ問題があります)。 2番目のアプローチでは2GBファイルでテストし、2分後には入力ファイルの隣に${fileName}_noCommentsというファイルがありました。

public static int LINES_BATCH = 10000; 

private static void scriptNoComment(String fileName) { 

    Path filePath = Paths.get(fileName); 
    try (Stream<String> stream = Files.lines(filePath); BufferedWriter fileOut = getFileOutWriter(fileName)) { 

    List<String> linesWithNoComments = new ArrayList<String>(); 

    stream.forEach(line -> { 

     if (line.startsWith("--")) { 
     return; 
     } 

     String currentLine = line; 

     int commentStartIndex = line.indexOf("--"); 
     if (commentStartIndex != -1) { 
     currentLine = line.substring(0, commentStartIndex); 
     } 

     currentLine = currentLine.toUpperCase(); 
     currentLine = currentLine.replaceAll("\"", ""); 
     currentLine = currentLine.replaceAll("\\r\\n|\\r|\\n", " "); 
     currentLine = currentLine.replaceAll("\\s+", " ").trim(); 

     if (currentLine.isEmpty()) { 
     return; 
     } 

     linesWithNoComments.add(currentLine); 

     if (linesWithNoComments.size() >= LINES_BATCH) { 
     writeCurrentBatchToFile(fileOut, linesWithNoComments); 
     } 

    }); 

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

private static BufferedWriter getFileOutWriter(String fileName) { 
    BufferedWriter fileOut; 
    try { 
    fileOut = new BufferedWriter(new FileWriter(fileName + "_noComments", false)); 
    return fileOut; 
    } catch (IOException e) { 
    throw new RuntimeException("Error while creating out writer", e); 
    } 
} 

private static void writeCurrentBatchToFile(BufferedWriter fileOut, List<String> linesWithNoComments) { 
    try { 

    for (String line : linesWithNoComments) { 
     fileOut.write(line + " "); 
    } 

    linesWithNoComments.clear(); 
    } catch(IOException e) { 
    throw new RuntimeException("Unable to write lines to file", e); 
    } 
} 
+0

'ArrayList'は' StringBuilder'よりも優れていません。ファイルサイズの初期容量で[StringWriter](https://docs.oracle.com/javase/7/docs/api/java/io/StringWriter.html)を使用する方が効果的です。 – gaborsch

1

ありがとうございました。あなたは文句を言わないのStringBufferを使用し、少ないメモリを利用することとして

あなただけの、これらのコメントを削除したいので

うまくいけば

int chk=strLine.indexOf("--"); 
     if(chk!=-1) 
     strLine = strLine.subtring(0,chk); 
    Out.append(strLine +"\n"); 

これはあなたの問題を解決して

if(strLine.contains("--")){ 
     strLine = strLine.replaceAll("--","\n--"); 
    } 
    strOut.append(strLine+"\n"); 

を交換してください。

+0

これは本当に役に立ちました。ありがとうございました – maryam

2

あなたの問題は、あなたが、あなたべき線でreadそのラインと、この場合の良い方法ではありませんどのthe entire file into memoryをロードするという事実のために、おそらくここに、あなたのPLSQLファイルが巨大であるとされたと仮定すると、コンテンツをStringとして返すのではなく、結果をtemporary filewriteとして返します。

書き込むのがもう少し複雑ですが、実際にはヒープサイズを4Goに増やすというよりはるかにスケーラブルなアプローチです。明日はファイルが2倍大きくなります。ヒープサイズは2倍になりますか?

関連する問題