从Java运行python脚本作为子进程

时间:2020-02-11 20:03:22

标签: java python

我正在尝试执行python代码(从控制台实时运行,而不仅仅是打开单个文件)。

ProcessBuilder builder = new ProcessBuilder("python");
Process process = builder.start();
new Thread(() -> {
    try {
        process.waitFor();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}).start();
new Thread(() -> {
    String line;
    final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    // Ignore line, or do something with it
    while (true) try {
        if ((line = reader.readLine()) == null) break;
        else System.out.println(line);
    } catch (IOException e) {
        e.printStackTrace();
    }
}).start();

final PrintWriter writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream()));
writer.println("1");
writer.println("2 * 2");

我尝试了这段代码,但是在尝试推送以下表达式12*2之后,我没有得到响应(表达式的求值)。

有人知道这个问题是什么吗?

1 个答案:

答案 0 :(得分:3)

您的python代码似乎无法打印任何内容,并且处理多个线程以读取和写入另一个进程是一个棘手的话题。幸运的是,该功能是内置的。你可以做

ProcessBuilder builder = new ProcessBuilder("/usr/bin/env", "python",
        "-c", "print(2*2); exit()");
builder.inheritIO();
try {
    Process process = builder.start();
    process.waitFor();
} catch (Exception e) {
    e.printStackTrace();
}

哪个输出

4

并终止。对于不太普通的Python和Java集成,强烈建议您使用here。至于您现有的代码,您永远不会exit() python,也永远不会flush()您的PrintWriter。然后您在main线程上写。而且您需要将-i传递给python,否则就不会假设stdin是控制台。将您的代码更改为

ProcessBuilder builder = new ProcessBuilder("/usr/bin/env", "python", "-i");
Process process = builder.start();

new Thread(() -> {
    String line;
    final BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
    // Ignore line, or do something with it
    while (true)
        try {
            if ((line = reader.readLine()) == null)
                break;
            else
                System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
}).start();
new Thread(() -> {
    final PrintWriter writer = new PrintWriter(
            new OutputStreamWriter(process.getOutputStream()));
    writer.println("1");
    writer.println("2 * 2");
    writer.println("exit()");
    writer.flush();
}).start();

似乎正常工作。