我在用 ProcessBuilder
在java中运行进程。我想让我的程序等待 Process
直到它的输出流有一行匹配给定的模式,或直到一个时间限制超过。
我用 BufferedReader
逐行阅读 Process.getOutputStream
同时将每一行与模式匹配。当存在匹配或进程在任何匹配之前终止时,它工作正常。但是,当进程在给定的时间限制之后不再输出行时 BufferedReader.readLine()
块和线程从 Process.getOutputStream
永远不会完成。
这是我的密码。
private static Timer setTimeout(Runnable runnable, long timeoutMillis) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runnable.run();
timer.cancel();
}
}, timeoutMillis);
return timer;
}
static CompletableFuture<Process> startProcessAndWaitForMatchedOutput(
ProcessBuilder processBuilder, String pattern, long waitForMillis) {
final CompletableFuture<Process> completableFuture = new CompletableFuture<>();
final Process process;
try {
process = processBuilder.start();
} catch (IOException ex) {
completableFuture.completeExceptionally(ex);
return completableFuture;
}
final Pattern compiledPattern = Pattern.compile(pattern);
final Timer timeoutTimer = setTimeout(() ->
completableFuture.completeExceptionally(new WaitForTimeExceededException()),
waitForMillis);
new Thread(() -> {
try (InputStream processOutputStream = process.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(processOutputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
/* The thread is blocked here.
Indeed the code call this method always return because
my completableFuture always completes.
But the problem is there is a running thread
which is a waste of resource. */
while ((line = bufferedReader.readLine()) != null) {
if (compiledPattern.matcher(line).matches()) {
completableFuture.complete(process);
timeoutTimer.cancel();
return;
}
}
completableFuture.completeExceptionally(new OutputDidNotMatchException());
timeoutTimer.cancel();
} catch (IOException ex) {
completableFuture.completeExceptionally(ex);
timeoutTimer.cancel();
}
}).start();
return completableFuture;
}
我的解决方法正确吗?如果没有,是否有一些库可以解决我的问题?
暂无答案!
目前还没有任何答案,快来回答吧!