6

私はJavaのProcessBuilderを使用してサブプロセスを開始しています。これは、別のJVMで実行する必要がある別のJavaプログラムです。

プロセスからのstdoutストリームとstderrストリームから読み取るために2つのスレッドを開始します。これにより、ストリームバッファーがいっぱいになってもハングしません。Process.waitForの呼び出しは返されますが、ストリームは終了しません。

私が使用しているコードは次のようになります(コマンドは文字列のリストです):

ProcessBuilder pb = new ProcessBuilder(command);

final Process p = pb.start();
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final ByteArrayOutputStream errStream = new ByteArrayOutputStream();

Thread outputThread = new Thread() {
    @Override
    public void run() {
        try {
            IOUtils.copy(p.getInputStream(), outStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    };
};
outputThread.start();

Thread errorThread = new Thread() {
    @Override
    public void run() {
        try {
            IOUtils.copy(p.getErrorStream(), errStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    };
};
errorThread.start();

int returncode = p.waitFor();
outputThread.join();
errorThread.join();

「java-version」や「dir」など、他の何かを実行すると、コードは正常に機能します。実行しようとしているJavaコードにアクセスできますが、System.outでclose()を呼び出す必要があるとは聞いたことがありません。

4

2 に答える 2

3

Apache commons exec がこれをすべて行います。はるかに簡単に...

http://commons.apache.org/exec/

于 2011-09-27T04:01:47.443 に答える
0

このウェブサイトから知っているように、 Process オブジェクトからのすべての std-streams を自分で閉じる必要があります。以前に使用されたかどうかに関係なく。これは、サブプロセスが終了した場合でも、明示的に閉じられていないときにパイプを開いたままにするG1ガベージコレクター(Java 7以降のデフォルト)に非常に関連しているようです。

ここの内部構造には詳しくありませんが、質問への回答に投稿したコードは、GhostScript などを頻繁に呼び出す 24 時間年中無休のシステムで正常に動作します。

Process の std-streams explicit を閉じる必要があることを示す SO に関するその他の質問と回答:

于 2011-09-19T15:23:02.343 に答える