46

我正在尝试OutputStream将由Process发起者exec()发送到控制台。如何才能做到这一点?

这是一些不完整的代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;

public class RuntimeTests
{
    public static void main(String[] args)
    {
        File path = new File("C:\\Dir\\Dir2");
        String command = "cmd /c dir";
        Reader rdr = null;
        PrintStream prtStrm = System.out;
        try
        {
            Runtime terminal = Runtime.getRuntime();

            OutputStream rtm = terminal.exec(command, null, path).getOutputStream();
            prtStrm = new PrintStream(rtm);
            prtStrm.println();
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
4

7 回答 7

114

我最近遇到了这个问题,只想提一下,从 java 7 开始,流程构建器 api已经扩展。现在可以通过以下方式解决此问题:

ProcessBuilder pb = new ProcessBuilder("yourcommand");
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
Process p = pb.start();
于 2012-08-30T15:26:59.310 回答
44

我相信这就是您正在寻找的:

  String line;
  Process p = Runtime.getRuntime().exec(...);
  BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
  while ((line = input.readLine()) != null) {
    System.out.println(line);
  }
  input.close();
于 2011-10-10T15:45:29.383 回答
12

我遇到了类似的问题,我正在使用以下代码。

Process p = Runtime.getRuntime().exec(".....");
p.waitFor();

String line;

BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while((line = error.readLine()) != null){
    System.out.println(line);
}
error.close();

BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=input.readLine()) != null){
    System.out.println(line);
}

input.close();

OutputStream outputStream = p.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.println();
printStream.flush();
printStream.close();
于 2012-10-16T09:00:49.497 回答
7

请参阅 Benjamin Gruenbaum 回答,涵盖自 Java 7 起可用的 ProcessBuilder API。

您需要启动一个新线程来读取在Process.waitFor(). 然后进程输出可以从该线程复制到控制台。

Process.getOutputStream()实际上是输入,即进程的标准输入。 Process.getInputStream()Process.getErrorStream()返回InputStream作为进程的标准输出和标准错误的对象。InputStreams 和是从调用者的OutputStream角度来看的,这与进程的角度相反。

进程的输出 stdout 是调用者的输入,因此调用者获取 agetInputStream()并从中读取 stdout:

Process proc = Runtime.getRuntime().exec(cmdArr, env, cwdir);

InputStreamReader isr = new InputStreamReader(proc.getInputStream());
BufferedReader rdr = new BufferedReader(isr);
while((line = rdr.readLine()) != null) { 
  System.out.println(line);
} 

isr = new InputStreamReader(proc.getErrorStream());
rdr = new BufferedReader(isr);
while((line = rdr.readLine()) != null) { 
  System.out.println(line);
} 
rc = proc.waitFor();  // Wait for the process to complete

Process.getOutputStream()用于调用者将数据“输出”到进程的标准输入中。可以在上面示例的第一行中创建“proc”之后添加此代码,以将数据发送到进程的标准输入:

// Send data to stdin of the process (in development, needs input content)
OutputStream os = proc.getOutputStream();
Bytes content = new Bytes("Hello\nasdf\n adma");
os.write(content.arr, content.off, content.length());
os.close(); // should use try/finally or try/resource

在读取输出之前执行上述操作。记得关闭OutputStream操作系统(使用 try/resource 或 try/finally)。因此,该进程知道标准输入是完整的,它可以完成对信息的处理。

于 2010-10-14T17:56:59.357 回答
5

我知道这是一个非常古老的问题,但上述答案的更好替代方案是

ProcessBuilder builder = new ProcessBuilder(command);
builder.inheritIO();
Process p = builder.start();

从 的文档中ProcessBuilder.inheritIO()

将子进程标准 I/O 的源和目标设置为与当前 Java 进程的相同。

希望这对某人有帮助!

于 2019-06-09T12:21:15.583 回答
2

VerboseProcessjcabi-log尝试:

String output = new VerboseProcess(new ProcessBuilder("foo.bat")).stdout();

该类启动一个后台线程,监听输出流并记录它。

于 2013-06-22T10:50:41.880 回答
2

如果您可以使用 commons-io 中的 org.apache.commons.io.IOUTils,

System.out.println(IOUtils.toString(process.getInputStream()));
System.err.println(IOUtils.toString(process.getErrorStream()));
于 2016-02-15T17:20:03.100 回答