来自apache-commons exec的进程输出

Jam*_*gon 26 java apache-commons apache-commons-exec

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

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

代码执行perl脚本,并在GUI运行时从GUI中显示stdout.

调用代码在swingworker内部.

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

通过谷歌找到这个并且工作得很好:

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());
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*son 30

不要传递ByteArrayOutputStreamPumpStreamHandler,使用抽象类的实现org.apache.commons.exec.LogOutputStream.像这样的东西:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后阻止调用exec.execute你的getLines()遗嘱后会出现标准输出和标准错误.的ExecutionResultHandler是从就在执行的过程中,并收集所有的STDOUT/STDERR成的行的列表的角度可选的.