获取 Java 进程在终止之前的标准输入

huangapple go评论79阅读模式
英文:

Get stdInput from a java Process before the process terminates

问题

我正在尝试运行一个Python脚本并希望获取脚本的标准输入,以便我可以使用它。我已经注意到标准输入会一直挂起,直到进程完成。

Python脚本:

import time
counter = 1
while True:
    print(f'{counter} hello')
    counter += 1
    time.sleep(1)

Java代码:

public class Main {

    public static void main(String[] args) throws IOException {
        Runtime rt = Runtime.getRuntime();
        String[] commands = {"python3", "/Users/nathanevans/Desktop/Education/Computing/Programming/Java/getting script output/src/python/main.py"};
        Process proc = rt.exec(commands);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

        System.out.println("命令的标准输出");
        String s = null;
        while ((s = stdInput.readLine()) != null) {
            System.out.println(s);
        }

        System.out.println("命令的标准错误");
        while ((s = stdError.readLine()) != null) {
            System.out.println(s);
        }
    }
}

在这种情况下,直到进程终止后,Java应用程序才会打印输出。

我如何获取脚本按原样写入的标准输入?

英文:

So I am trying to run a python script and want to obtain the stdInput from the script so I can use it. I have noticed the stdInput will hang until the process has finished.

Python script:

import time
counter = 1
while True:
    print(f'{counter} hello')
    counter += 1
    time.sleep(1)

Java code:

public class Main {

    public static void main(String[] args) throws IOException {
        Runtime rt = Runtime.getRuntime();
        String[] commands = {"python3", "/Users/nathanevans/Desktop/Education/Computing/Programming/Java/getting script output/src/python/main.py"};
        Process proc = rt.exec(commands);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

        System.out.println("stdOuput of the command");
        String s = null;
        while ((s = stdInput.readLine()) != null) {
            System.out.println(s);
        }

        System.out.println("stdError of the command");
        while ((s = stdError.readLine()) != null) {
            System.out.println(s);
        }
    }
}

Nothing is printed from the java application until the Process is terminated but in this case when I terminate the java application.

How would I obtain the stdInput as it is written by the script?

答案1

得分: 0

为了立即获得Python输出,您需要关闭Python输出缓冲 - 相关内容在这里有详细介绍。

这可能会解决您的问题,但您可能会遇到第二个问题,因为您正在一个线程中读取标准输入/输出。如果标准错误缓冲区在您读取标准输入的末尾之前被填满,它将阻塞进程。解决方案是在单独的线程中读取标准输入/输出/错误,或者使用ProcessBuilder,它允许重定向到文件或将标准错误重定向到标准输出:

ProcessBuilder pb = new ProcessBuilder(commands);
pb.redirectOutput(outfile);
pb.redirectError(errfile);
// 或者
pb.redirectErrorStream(true);
Process p = pb.start();
英文:

In order to get Python output immediately you'd need to turn off Python output buffering - that is covered here

This may fix your problem but you may run into second issue because you are reading STD IN / OUT in one thread. If STDERR buffer fills before you read to end of STDIN it will block the process. The solution then is to read STD/IN/ERR in separate threads or use ProcessBuilder which allows redirect to files or redirect STDERR to STDOUT:

ProcessBuilder pb = new ProcessBuilder(commands);
    pb.redirectOutput(outfile);
    pb.redirectError(errfile);
//or
    pb.redirectErrorStream(true);
Process p = pb.start();

huangapple
  • 本文由 发表于 2020年9月9日 17:49:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63809075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定