Я нахожусь здесь на своем пути. Я уверен, что это что-то простое, и у меня, скорее всего, есть огромные дыры в моем понимании java и потоков. Я думаю, что существует так много классов, что я немного перегружен попытками проникнуть через API, чтобы выяснить, когда и как я хочу использовать множество потоков ввода/вывода.
Я только что узнал о существовании библиотеки apache commons (самообучение java fail), и в настоящее время я пытаюсь преобразовать часть моего Runtime.getRuntime(). exec для использования commons - exec. Уже исправлено несколько раз, каждые 6 месяцев эта проблема возникает, а затем устраняет проблемы стиля с exec.
Код выполняет perl script и отображает stdout из script в графическом интерфейсе, когда он запущен.
Вызывающий код находится внутри 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, в основном снова перейдя от найденного 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();
Я пытаюсь выяснить, что делает handstreamhandler. Я предполагаю, что это приведет к выходу из объекта exec и заполнит OutputStream. Я предоставляю ему байты из perl script stdout/err?
Если да, то как бы вы получили вышеприведенное поведение, чтобы поток был потоковым потоком? В примерах люди показывают, что вы вызываете out.toString() в конце, и я предполагаю, что это просто даст мне дамп всего вывода из script после его выполнения? Как бы вы сделали это так, чтобы он показывал результат, поскольку он работает по строкам?
------------ Future Edit ---------------------
Обнаружено это через 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());
}