我希望能够从Java生成外部进程,并定期写入其输入并读取响应,就好像它是控制台一样。但是,在我阅读流程输出时,大部分时间都没有。有没有做好这种事情的好习惯(甚至避免它)?
以下是一个不起作用的简要示例:
import org.apache.commons.exec.*;
import java.io.*;
//...
CommandLine cl = CommandLine.parse("/usr/bin/awk {print($1-1)}");
System.out.println(cl.toStrings());
Process proc = new ProcessBuilder(cl.toStrings()).start();
OutputStream os = proc.getOutputStream(); // avoiding *Buffered* classes
InputStream is = proc.getInputStream(); // to lessen buffering complications
os.write(("4" + System.getProperty("line.separator")).getBytes());
os.flush(); // Doesn't seem to flush.
// os.close(); // uncommenting works, but I'd like to keep the process running
System.out.println("reading");
System.out.println(is.read()); // read even one byte? usually is.available() -> 0
奇怪的是,如果我在BufferedWriter中包装OutputStream,我可以从一些进程(cat)读取,但不能读取其他进程(awk,grep)。
答案 0 :(得分:1)
通常,采取的方法是正确的。但事情很少:
InputStream.read()
是一种阻止方法。它等待输入并且不是CPU密集型的。你应该围绕它...... read(byte[] buffer, int offset, int len)
readLine()
方法)。这是BufferedReader的替代方案。Process.waitFor()
。此外,请确保外部进程写入标准输出(而不是标准错误)。这里有两种可能性:
Process.getErrorStream()
(并将其视为另一个InputStream)/usr/bin/awk {print($1-1)} 2>&1
。这会将标准错误重定向到标准输出。