java代码中的流_如何处理Java中的多个流?

实际上,您必须为要监视的每个流生成一个线程。如果您的用例允许组合相关进程的stdout和stderr,那么您只需要一个线程,否则需要两个线程。

我花了相当长的时间才完成了一个项目,在这个项目中,我必须启动一个外部进程,在它的输出端做一些事情,同时寻找错误和进程终止,并且当Java应用程序的用户取消操作时,也可以终止它。

我创建了一个相当简单的类来封装监视部分,其run()方法如下所示:

public void run() {

BufferedReader tStreamReader = null;

try {

while (externalCommand == null && !shouldHalt) {

logger.warning("ExtProcMonitor("

+ (watchStdErr ? "err" : "out")

+ ") Sleeping until external command is found");

Thread.sleep(500);

}

if (externalCommand == null) {

return;

}

tStreamReader =

new BufferedReader(new InputStreamReader(watchStdErr ? externalCommand.getErrorStream()

: externalCommand.getInputStream()));

String tLine;

while ((tLine = tStreamReader.readLine()) != null) {

logger.severe(tLine);

if (filter != null) {

if (filter.matches(tLine)) {

informFilterListeners(tLine);

return;

}

}

}

} catch (IOException e) {

logger.logExceptionMessage(e, "IOException stderr");

} catch (InterruptedException e) {

logger.logExceptionMessage(e, "InterruptedException waiting for external process");

} finally {

if (tStreamReader != null) {

try {

tStreamReader.close();

} catch (IOException e) {

// ignore

}

}

}

}

在主叫方,情况如下:

Thread tExtMonitorThread = new Thread(new Runnable() {

public void run() {

try {

while (externalCommand == null) {

getLogger().warning("Monitor: Sleeping until external command is found");

Thread.sleep(500);

if (isStopRequested()) {

getLogger()

.warning("Terminating external process on user request");

if (externalCommand != null) {

externalCommand.destroy();

}

return;

}

}

int tReturnCode = externalCommand.waitFor();

getLogger().warning("External command exited with code " + tReturnCode);

} catch (InterruptedException e) {

getLogger().logExceptionMessage(e, "Interrupted while waiting for external command to exit");

}

}

}, "ExtCommandWaiter");

ExternalProcessOutputHandlerThread tExtErrThread =

new ExternalProcessOutputHandlerThread("ExtCommandStdErr", getLogger(), true);

ExternalProcessOutputHandlerThread tExtOutThread =

new ExternalProcessOutputHandlerThread("ExtCommandStdOut", getLogger(), true);

tExtMonitorThread.start();

tExtOutThread.start();

tExtErrThread.start();

tExtErrThread.setFilter(new FilterFunctor() {

public boolean matches(Object o) {

String tLine = (String)o;

return tLine.indexOf("Error") > -1;

}

});

FilterListener tListener = new FilterListener() {

private boolean abortFlag = false;

public boolean shouldAbort() {

return abortFlag;

}

public void matched(String aLine) {

abortFlag = abortFlag || (aLine.indexOf("Error") > -1);

}

};

tExtErrThread.addFilterListener(tListener);

externalCommand = new ProcessBuilder(aCommand).start();

tExtErrThread.setProcess(externalCommand);

try {

tExtMonitorThread.join();

tExtErrThread.join();

tExtOutThread.join();

} catch (InterruptedException e) {

// when this happens try to bring the external process down

getLogger().severe("Aborted because auf InterruptedException.");

getLogger().severe("Killing external command...");

externalCommand.destroy();

getLogger().severe("External command killed.");

externalCommand = null;

return -42;

}

int tRetVal = tListener.shouldAbort() ? -44 : externalCommand.exitValue();

externalCommand = null;

try {

getLogger().warning("command exit code: " + tRetVal);

} catch (IllegalThreadStateException ex) {

getLogger().warning("command exit code: unknown");

}

return tRetVal;

不幸的是,对于一个独立的可运行的示例,我不必这样做,但这可能会有所帮助。

如果我必须再做一次,我将使用thread.interrupt()方法而不是自制的停止标志(请注意声明它是volatile!)但是我把它留了一段时间。:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值