Я в своем уме. Я уверен, что это что-то простое, и у меня, скорее всего, есть огромные пробелы в моем понимании Java и потоков. Я думаю, что существует так много классов, что я немного ошеломлен попыткой пробраться через API, чтобы выяснить, когда и как я хочу использовать множество потоков ввода / вывода.
Я только что узнал о существовании библиотеки Apache Commons (самообучающийся Java-сбой), и в настоящее время пытаюсь преобразовать часть моего Runtime.getRuntime (). Exec для использования commons - exec. Уже исправлено несколько раз в 6 месяцев, когда эта проблема возникает, а затем исчезает проблема стиля с exec.
Код выполняет сценарий perl и отображает стандартный вывод сценария в графическом интерфейсе во время его работы.
Код вызова находится внутри работника качания.
Я заблудился, как использовать 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, по сути, опять же из кода найденного Google:
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 и заполнит OutputStream. Я предоставляю ему байты из stdout / err сценария perl?
Если это так, как бы вы получили приведенное выше поведение, чтобы оно выводило вывод построчно? В примерах люди показывают, что вы вызываете 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());
}