Выполнение внешней программы с использованием компоновщика процессов или apache commons exec
Мне нужно выполнить внешнее приложение, которое возвращает большие данные (занимает более 2 часов) и постоянно выводит данные.
Что мне нужно сделать, это выполнить эту программу асинхронно и записать вывод в файл. Я попытался с помощью Java Process Builder, однако кажется, что он зависает и возвращает вывод только тогда, когда программа закрывается или принудительно завершается.
Я попытался использовать построитель процессов и обновил новый поток, чтобы захватить вывод, но все равно это не помогло.
Затем я прочитал об Apache Commons Exec и попробовал то же самое. однако это также, кажется, занимает много времени и возвращает разные коды ошибок (для одного и того же ввода)
CommandLine cmdLine = new CommandLine("/opt/testsimulator");
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
Executor executor = new DefaultExecutor();
executor.setStreamHandler(psh);
executor.setWatchdog(watchdog);
try {
executor.execute(cmdLine);
} catch (ExecuteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Любая помощь или рабочие примеры будут очень полезны
1 ответ
Да. С помощью ProcessBuilder
должно работать для вашей конфигурации. Например, у меня работает следующий шаблон:
ProcessBuilder pb = new ProcessBuilder("/tmp/x");
Process process = pb.start();
final InputStream is = process.getInputStream();
// the background thread watches the output from the process
new Thread(new Runnable() {
public void run() {
try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
is.close();
}
}
}).start();
// the outer thread waits for the process to finish
process.waitFor();
Программа, которую я запускаю - это всего лишь сценарий с целой кучей sleep 1
а также echo
линии:
#!/bin/sh
sleep 1
echo "Hello"
sleep 1
echo "Hello"
...
Чтение потока из процесса выплевывает Hello
каждую секунду или около того.