从java执行外部进程。在进程终止后获得输出,但在终止之前需要它

时间:2011-07-19 02:44:28

标签: java process live execution

为什么我在流程终止后得到流程的输出?我需要让流程输出“实时”,而流程正在运行,而不是在流程终止后。我想运行一个像jboss这样的进程,它正在登录标准输出,因此我需要及时获取该信息,而不是在进程终止后。谢谢你的回答。

这是我的代码:

        try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        while ((line = processReader.readLine()) != null) {
            System.out.println(line);
          }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

扩展:

所以我想用带按钮的eclipse插件运行一个外部程序。当我点击按钮时,程序启动,外部程序的输出将返回控制台。当我点击停止时,程序停止。这就是我如何制作流程构建器的实例。我创建了一个示例类来测试流程构建器,而无需在每次修改中启动整个插件项目。

这是我的流程构建器实例,它实现了Runnable:

@Override
public void run() {
    List<String> command = new ArrayList<String>();
    command.add(serverPath);
    command.add(String.valueOf(count));
    command.add(filePath);
    processBuilder = new ProcessBuilder(command);
    processBuilder.redirectErrorStream(true);

    try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        System.out.println(process.waitFor());
        while ((line = processReader.readLine()) != null) {
            System.out.println(line);

        }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

参数来自构造函数。这是实例化:

public static void main(String[] args) throws Exception

{

 SimulationProcess smp = new SimulationProcess(count, "file",
            "program_name");
    smp.run();

}

2 个答案:

答案 0 :(得分:4)

您可以尝试解决一些问题:

a)制作测试程序并使用上面的代码运行它以确保您可以正确阅读。例如:

public static void main(String[] args) {
  for(;;) {
    try {
      Thread.sleep(5000);
      System.out.println("Test output");
    } catch(InterruptedException e) {
      // Ignore
    }

  }
}

b)确保您正在处理进程的错误流 - 如果您不处理错误流,进程可能会锁定。查看this site以获取有关使用Java的ProcessBuilder或Runtime.exec()时要避免的事项的教程 - 它包含一个StreamGobbler的实现,它将丢弃您不关心的流上的所有数据。 / p>

c)尝试使用System.out.flush() - 可能是您的输出正在缓冲。

编辑:感谢您的更新。你的问题在这里:

System.out.println(process.waitFor()); // Waits for the process to exit.
while ((line = processReader.readLine()) != null) {
    System.out.println(line);
}

如果删除waitFor(),它将继续打印直到流关闭。流应该只在进程终止时关闭。您应该在循环后放置waitFor()吗?

答案 1 :(得分:0)

也许你的输出不包含换行符,这样你的while循环在进程完成之前就不会做任何事情。

尝试使用另一种不等待换行符的读取方法,例如:

char[] cbuf = new char[10];
while(processReader.read(cbuf) != -1)
{
  System.out.print(cbuf);
}