如何使用 Java 中子进程的 OutputStream?

How do I use the OutputStream from a subprocess in Java?

我使用 ProcessBuilder 创建了一个流程:

ProcessBuilder processBuilder = new ProcessBuilder(group.getExec().split(" "))
        .redirectErrorStream(true));
Process process = processBuilder.start();

目前我得到了 InputStream 并将其显示到控制台:

InputStream std_out = process.getInputStream();
new Thread(() -> {
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(std_out));
        String line;
        while((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();
    } catch(IOException e) {
        e.printStackTrace();
    }}).start();

当我尝试在子进程启动后在控制台中写入任何内容时,没有任何反应 - 正如预期的那样。如何启用它以便我有一个交互式终端?

编辑:更具体地说,我正在尝试编写命令并将它们发送到子进程。

group.getExec().split(" ")

这太脆弱了。为什么不直接通过 group.getExec()? ProcessBuilder 的特定使用模式的 'split on whitespace' 解析能力不是很好,但至少比这要好。只需删除 .split(" ").

BufferedReader reader = new BufferedReader(new InputStreamReader(std_out));

在网络上搜索 'java try with resources' 并在此处应用;这是漏水的。

} catch(IOException e) { e.printStackTrace();

这不是您进行异常处理的方式。如果你不想处理这个问题,正确的“我只是不关心”处理程序是 throw new RuntimeException("Uncaught", e);,因为它保留了 所有 问题的相关信息 and 确保不会执行处于意外状态的代码。

To be more specific, I am trying to write commands and send them to the subprocess.

正如有getInputStream()方法一样,也有getOutputStream()方法。你会发送你的命令,你不能那么容易地将你的 java 进程的终端连接到启动的子进程。你不需要分离一个单独的线程,你可以使用你所在的线程,但如果你想单独响应子进程退出,你 需要 3 个线程(一个阻止子进程将数据发送到您的 java 进程 - 这是您已经拥有的线程,一个等待用户键入内容,一旦他们按下回车,它就会将其发送到子进程,另一个等待直到存在子进程 (process.waitFor())).