2012-01-18 6 views
0

私は、次の作品やってプログラムを書いています:プロセスの入力ストリームから読み込み、指定されたメソッドを使用して処理する方が良いでしょうか?

  1. は(「SVN情報」または「SVN差分」のような)ProcessBuilderをを使用してコマンドを実行します。
  2. プロセスのgetInputStream()からコマンドの出力を読み取ります。
  3. コマンドの出力では、私はどちらか欲しい:
    • は、出力を解析し、私が欲しいものを手に入れると、後でそれを使用し、OR:
    • は、指定したファイルに出力を直接書きます。

今、私がやっているものを線でどんなコマンドの出力を読み、ArrayListに保存し、その後、私はちょうど何かを見つけるために走査線や線を書くかどうかを決定するBufferedReaderを使用していますファイルに。

明らかに、これはコマンドの出力をファイルに保存するにはArrayListを必要としないため、醜い実装です。だから、より良い方法でそれをするために何を提案しますか?

ArrayList<String> reuslt = runCommand(command1); 

for (String line: result) { 
    // ...parse the line here... 
} 

コマンドを実行し、プロセス

private ArrayList<String> runCommand(String[] command) throws IOException { 
    ArrayList<String> result = new ArrayList<>(); 
    _processBuilder.command(command); 

    Process process = null; 
    try { 
     process = _processBuilder.start(); 
     try (InputStream inputStream = process.getInputStream(); 
     InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 
     BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { 
      String line; 
      while ((line = bufferedReader.readLine()) != null) { 
       result.add(line); 
      } 
     } 
    } 
    catch (IOException ex) { 
     _logger.log(Level.SEVERE, "Error!", ex); 
    } 
    finally { 
     if (process != null) { 
      try { 
       process.waitFor(); 
    } 
      catch (InterruptedException ex) { 
       _logger.log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

return result; 
} 

、私はこのように行うことができる1つの方法での出力から読み取るために、これを使用します。ここでは

は、私のコードのいくつかはあります

と私は次のようになります:

ArrayList<String> result = runCommand(command2); 
File file = new File(...filename, etc...); 

try (PrintWriter printWriter = new PrintWriter(new FileWriter(file, false))) { 
    for (String line: result) { 
     printWriter.println(line); 
    } 
} 

答えて

1

ArrayListでプロセス出力を返すことは、私にとっては素晴らしい抽象化のようです。その後、runCommand()の呼び出し元は、コマンドの実行方法や出力の読み込みを心配する必要はありません。余分なリストで使用されるメモリは、あなたのコマンドが非常に派生していない限り、おそらく重要ではありません。

この問題が発生するのは、コマンドがまだ実行されている間に呼び出し元が出力処理を開始したいと思う唯一の時間です。ここではそうではありません。

最初にメモリにコピーしたくない非常に大きな出力の場合、1つのオプションは、出力の各行を呼び出すようにGuayaのLineProcessorのようなコールバックをrunCommand()にすることです。その後、runCommand()は、プロセスを実行して出力を読み取り、その後すべてをクローズすることができますが、メソッドが1つの配列内の応答全体を返すのを待つのではなく、実行時にコールバックに渡すことができます。

+0

私が追加したことは、svn diffのようなコマンドが10MBを超える出力を生成することがあるということです。 – coolcfan

+0

OK、上記の編集をご覧ください。 –

+0

ああ、同じインタフェースを実装しているプロセッサをいくつか書くことができ、そのうちの1つをrunCommandメソッドのパラメータとして渡すことができますか? – coolcfan

0

場合によってはテキストを無駄に保存するのはパフォーマンス上の問題ではないと思います。それにもかかわらず、清潔さのために、それは二つの方法書くために良いかもしれない:

private ArrayList<String> runCommand(String[] command) 

private void runCommandAndDumpToFile(String[] command, File file) 

を(それはあなたの質問からかなり明確ではなかったが、私はあなただけの出力を書きますかどうか、あなたのプロセスを実行する前に、知っていることを前提としていそれをファイル化または処理する。)

関連する問題