4

Python スクリプトがあり、完了するまでに時間がかかります。Javaから実行したいのですが、実行中にスクリプトの出力も出力して、正しく実行されているかどうかを確認できるようにします。

システムコマンドの実行中ではなく、終了後に出力を出力する例のみを検索して見つけました。

スクリプトの実行中にそれを行う方法はありますか?

これが私が持っているものです

public void doSomething() throws IOException {
    String[] callAndArgs = {"python", "/hi.py"};
    Process p = Runtime.getRuntime().exec(callAndArgs);
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));

    String s;
    while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
    }

    while ((s = stdError.readLine()) != null) {
        System.out.println(s);
    }
}
4

4 に答える 4

4

私はそれを次のように機能させることができました(Java7が必要であることに注意してください):

package test;
import java.lang.ProcessBuilder.Redirect;

public class Test {

    public static void main(String... args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("python","/home/foobar/Programming/test/src/test/test.py");
        pb.redirectOutput(Redirect.INHERIT);
        Process p = pb.start();
        p.waitFor();
    }

}

python(sys.stdout.flush()を使用して動作させるためにpythonでフラッシュすることに注意してください)

import time,sys
c =0
while c<=50:
    time.sleep(1)
    print("----")
    c = c +1
    sys.stdout.flush()

ループでフラッシュしたくない場合は、これを使用できます。

ProcessBuilder pb = new ProcessBuilder("python","-u","/home/foobar/Programming/NetBeansProjects/test/src/test/test.py");

Redirect.INHERIT

サブプロセスの I/O ソースまたは宛先が現在のプロセスのものと同じであることを示します。これは、ほとんどのオペレーティング システム コマンド インタープリター (シェル) の通常の動作です。

于 2013-09-30T21:27:22.447 に答える
2

システムコマンドの実行中ではなく、終了後に出力を出力する例のみを検索して見つけました。

コマンドの実行中に例が出力をダンプする必要があるため、これは奇妙です。

プロセスが終了するまで readLine に必要な条件が満たされない可能性があるため、を使用BufferedReaderする代わりに から直接読み取ってみることができます。InputStream

ProcessBuilderまた、 over を直接使用することをお勧めしますProcess。これは、他のものとは別に、出力をエラーストリームから入力ストリームにリダイレクトできるため、2 つではなく 1 つのストリームのみを読み取ることができるためです...

これは、Python の問題であり、出力バッファをフラッシュする方法にも問題がある可能性があります...

たとえば、BufferedReaderがいつ戻るかを決定するのを待つのではなく、発生/報告されたときにストリームから各文字を出力してみてください

            ProcessBuilder pb = new ProcessBuilder("test.py");
            pb.redirectError();
            Process p = pb.start();

            InputStream is = null;
            try {
                is = p.getInputStream();
                int in = -1;
                while ((in = is.read()) != -1) {
                    System.out.print((char)in);
                }
            } finally {
                try {
                    is.close();
                } catch (Exception e) {
                }
            }

アップデート

少し読んでみると、Python は stdout に送信する前にバッファリングしているようです。Java側でこれを修正できるとは思いませんが、Pythonの実行方法またはスクリプトの動作を変更する必要があります。

Python print の出力をフラッシュする方法を参照してください。詳細については

于 2013-09-30T20:26:16.600 に答える
0

while ループの条件として #readLine を使用しないでください。代わりに、スキャナーで inputStream をラップし、 #hasNextLine() を使用します

    Scanner in = new Scanner(p.getInputStream());
    while (in.hasNextLine()) {
        System.out.println(in.nextLine());
    }
于 2013-09-30T20:19:20.107 に答える