0

私は次の作業を行うプログラムを書いています。

  1. ProcessBuilderを使用してコマンドを実行します(「svninfo」や「svndiff」など)。
  2. プロセスのgetInputStream();からコマンドの出力を読み取ります。
  3. コマンドの出力で、私は次のいずれかが必要です。
    • 出力を解析し、必要なものを取得して後で使用する、または:
    • 指定されたファイルに出力を直接書き込みます。

今私がしているのはBufferedReader、コマンドが出力するものをすべて行で読み取り、それらをに保存してからArrayList、行をスキャンして何かを見つけるか、ファイルに行を書き込むかを決定することです。

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

これが私のコードのいくつかです:

これを使用してコマンドを実行し、プロセスの出力から読み取ります

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> reuslt = runCommand(command1);

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

そして別の場合、私はこのようにするかもしれません:

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);
    }
}
4

2 に答える 2

1

ArrayListでプロセス出力を返すことは、私にはすばらしい抽象化のように思えます。そうすれば、の呼び出し元はrunCommand()、コマンドがどのように実行されたか、または出力が読み取られたかを心配する必要はありません。コマンドが非常に複雑でない限り、追加リストで使用されるメモリはおそらく重要ではありません。

これが問題であることがわかったのは、コマンドの実行中に呼び出し元が出力の処理を開始したい場合だけでしたが、ここではそうではないようです。

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

于 2012-01-18T03:29:26.920 に答える
0

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

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

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

(質問からは明確ではありませんでしたが、プロセスを実行する前に、出力をファイルに書き込むか処理するかを知っていると思います。)

于 2012-01-18T03:47:04.247 に答える