来自apache-commons exec的进程输出 [英] Process output from apache-commons exec

查看:281
本文介绍了来自apache-commons exec的进程输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里结束了我的智慧。我确信这很简单,我很可能在理解java和流时遇到很大漏洞。我认为有这么多的课程让我有点不知所措,试图通过API来弄清楚我何时以及如何使用大量的输入/输出流。

I am at my wits end here. I'm sure this is something simple and I most likely have huge holes in my understanding of java and streams. I think there are so many classes that I'm a bit overwhelmed with trying to poke through the API to figure out when and how I want to use the multitude of input/output streams.

我刚刚了解了apache commons库的存在(自学java失败),我正在尝试将我的一些Runtime.getRuntime()。exec转换为使用commons - exec。已经修复了每6个月一次的问题,然后这个问题就出现了,然后消除了exec的样式问题。

I just learned about the existence of the apache commons library (self teaching java fail), and am currently trying to convert some of my Runtime.getRuntime().exec to use the commons - exec. Already it's fixed some of the once every 6 months this problem crops up then goes away style problems with exec.

代码执行一个perl脚本,并显示来自的stdout GUI中的脚本正在运行。

The code executes a perl script, and displays the stdout from the script in the GUI as it is running.

调用代码在swingworker内。

The calling code is inside of a swingworker.

我迷路了如何使用pumpStreamHandler。 ..无论如何这里是旧代码:

I'm getting lost how to use the pumpStreamHandler... anyway here is the old code:

String pl_cmd = "perl script.pl"
Process p_pl = Runtime.getRuntime().exec( pl_cmd );

BufferedReader br_pl = new BufferedReader( new InputStreamReader( p_pl.getInputStream() ) );

stdout = br_pl.readLine();
while ( stdout != null )
{
    output.displayln( stdout );
    stdout = br_pl.readLine();
}

我想这是我得到的复制粘贴代码我不完全很久以前就明白了。上面我假设正在执行该过程,然后抓取输出流(通过getInputStream?),将其放入缓冲读取器,然后将循环直到缓冲区为空。

I guess this is what I get for copy pasting code I don't fully understand a long time ago. The above I assume is executing the process, then grabs the outputstream (via "getInputStream"?), places it into a buffered reader, then will just loop there until the buffer is empty.

我没有得到的是为什么这里不需要'waitfor'样式命令?是否可能有一段时间缓冲区将为空,退出循环,并在进程仍在进行时继续?当我运行它时,情况似乎并非如此。

What I don't get is why there is no need for a 'waitfor' style command here? Isn't it possible that there will be some time in which the buffer will be empty, exit the loop, and continue on while the process is still going? When I run it, this doesn't seem to be the case.

无论如何,我试图使用commons exec获得相同的行为,基本上再一次来自谷歌找到的代码:

In any event, I'm trying to get the same behavior using commons exec, basically again going from google found code:

DefaultExecuteResultHandler rh = new DefaultExecuteResultHandler();
ExecuteWatchdog wd  = new ExecuteWatchdog( ExecuteWatchdog.INFINITE_TIMEOUT );
Executor exec = new DefaultExecutor();

ByteArrayOutputStream out = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler( out );

exec.setStreamHandler( psh );
exec.setWatchdog( wd );

exec.execute(cmd, rh );
rh.waitFor();

我正在试图找出pumpstreamhandler正在做什么。我假设这将从exec对象获取输出,并填充OutputStream我提供它与perl脚本的stdout / err中的字节?

I'm trying to figure out what pumpstreamhandler is doing. I assume that this will take the output from the exec object, and fill the OutputStream I provide it with the bytes from the perl script's stdout/err?

如果是这样,怎么会你得到上述行为让它逐行流输出?在示例中,人们显示最后调用out.toString(),并且我认为这只会在脚本运行完毕后从脚本中转储所有输出?你会怎么做才能显示输出,因为它是逐行运行的?

If so how would you get the above behavior to have it stream the output line by line? In examples people show you call the out.toString() at the end, and I assume this would just give me a dump of all the output from the script once it is done running? How would you do it such that it would show the output as it is running line by line?

------------未来编辑 - --------------------

------------Future Edit ---------------------

通过谷歌找到这个并且也很好用:

Found this via google and works nice as well:

public static void main(String a[]) throws Exception
{
    ByteArrayOutputStream stdout = new ByteArrayOutputStream();
    PumpStreamHandler psh = new PumpStreamHandler(stdout);
    CommandLine cl = CommandLine.parse("ls -al");
    DefaultExecutor exec = new DefaultExecutor();
    exec.setStreamHandler(psh);
    exec.execute(cl);
    System.out.println(stdout.toString());
}


推荐答案

不要传递 ByteArrayOutputStream PumpStreamHandler ,使用抽象类的实现 org.apache.commons.exec .LogOutputStream 。这样的事情:

Don't pass a ByteArrayOutputStream to the PumpStreamHandler, use an implementation of the abstract class org.apache.commons.exec.LogOutputStream. Something like this:

import java.util.LinkedList;
import java.util.List;
import org.apache.commons.exec.LogOutputStream;

public class CollectingLogOutputStream extends LogOutputStream {
    private final List<String> lines = new LinkedList<String>();
    @Override protected void processLine(String line, int level) {
        lines.add(line);
    }   
    public List<String> getLines() {
        return lines;
    }
}

然后在阻止调用 exec.execute 您的 getLines()将出现您要查找的标准输出和标准错误。从执行流程的角度来看, ExecutionResultHandler 是可选的,并将所有stdOut / stdErr收集到一个行列表中。

Then after the blocking call to exec.execute your getLines() will have the standard out and standard error you are looking for. The ExecutionResultHandler is optional from the perspective of just executing the process, and collecting all the stdOut/stdErr into a list of lines.

这篇关于来自apache-commons exec的进程输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆