我到了崩溃的边缘。我确定这是一些简单的东西,我很可能对Java和Streams有很大的理解漏洞。我认为有太多的类让我有点不知所措,试图浏览API以找出何时以及如何使用各种输入/输出流。
我刚刚了解到apache commons库的存在(自学Java失败),目前正在尝试将我的Runtime.getRuntime().exec的一些内容转换为使用commons-exec。这已经修复了执行中每6个月出现一次的问题,然后就会消失的风格问题。
代码执行一个perl脚本,并在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();
}
我想这就是当我复制粘贴自己不完全理解的代码一段时间后得到的结果。上面的代码应该是执行进程,然后通过“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();
我正在尝试弄清楚pumpstreamhandler在做什么。我认为它会获取exec对象的输出,并使用来自Perl脚本的stdout/err的字节填充我提供的OutputStream?如果是这样,您要如何获得上述行为以使其逐行流式传输输出?在示例中,人们向您展示如何在最后调用out.toString(),我想这只会在脚本运行完成后给出所有输出的转储。如何使它逐行显示输出,而不是一次性显示所有输出?
------------ 未来编辑 ---------------------
通过Google找到了这个,效果也很好:
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());
}