0

I would like to be able to spawn an external process from Java, and periodically write to its input and read the response as if it were the console. Much of the time, however, when I read the process' output, nothing is available. Is there a good practice to do this sort of thing (even avoiding it)?

Here's a stripped down example of what doesn't work:

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

Strangely, if I wrap up the OutputStream in a BufferedWriter, the I can read from some processes (cat), but not others (awk, grep).

4

1 回答 1

1

一般来说,采取的方法是适当的。不过有几件事:

  1. InputStream.read()是一种阻塞方法。它等待输入并且不是 CPU 密集型的。你应该围绕它...
  2. 可以读取多个字节,只需使用read(byte[] buffer, int offset, int len)
  3. 将输入流包装到 BufferedInputStream 简化了访问(readLine()方法)。这是 BufferedReader 的替代方案。
  4. 不要忘记使用Process.waitFor().

此外,确保外部进程写入标准输出(而不是标准错误)。这里有两种可能:

  1. 使用Process.getErrorStream()(并将其视为另一个 InputStream)
  2. 将命令行更改为. 这会将标准错误重定向到标准输出。/usr/bin/awk {print($1-1)} 2>&1
于 2012-10-31T15:06:48.630 回答