问题
I start a python script in my java application with
Process p = Runtime.getRuntime().exec("python script.py");
This script runs in a loop and is only canceled by an event (or user interaction). The script writes to the output every loop cycle, some text like "12:22:35 -- Heartbeat"
while True:
print("Heartbeat")
time.sleep(1)
In my Java application I want to read this output as it appears. My problem is, if I use the BufferReader, it will wait until the process is completed and after that it reads the output. Here is how I read it:
BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = is.readLine()) != null)
System.out.println(line);
How can I read the output "live"?
For better understanding: the python-script listen on a hardware button, and when this button is pressed, some output is written out. And in my java application I want to show up this message and sent it to some clients.
回答1:
Using https://github.com/zeroturnaround/zt-exec
new ProcessExecutor().command("python", "script.py")
.redirectOutput(new LogOutputStream() {
@Override
protected void processLine(String line) {
...
}
})
.execute();
回答2:
I've often written something like:
class StreamHandler extends Thread {
InputStream is;
Writer writer;
StreamHandler(InputStream is, Writer writer) {
super("StreamHandler");
this.is = is;
this.writer = writer;
}
@Override
public void run() {
try (InputStreamReader isr = new InputStreamReader(is)) {
char buffer[] = new char[256];
int n;
while ((n = isr.read(buffer)) > 0) {
writer.write(buffer, 0, n);
}
} catch (IOException e) {
System.err.println("StreamHandler: " + e);
}
}
}
While I've used this for capturing the output stream to my own buffer, you could simply echo to stdout in real time like:
Process process = Runtime.getRuntime().exec(...);
Writer writer = new OutputStreamWriter(System.out);
StreamHandler stdout_handler = new StreamHandler(process.getInputStream(), writer);
stdout_handler.start();
回答3:
try changing your python code to:
while True:
print("Heartbeat", flush=True)
time.sleep(1)
I've been trying to do the same as you and found this solution on this question: PumpStreamHandler can capture the process output in realtime
来源:https://stackoverflow.com/questions/41991147/read-live-output-of-process-in-java