2009-12-05 3 views
2

Я пытаюсь запустить экземпляр программы VideoLAN из приложения java. Один из способов, я пытался сделать это показано здесь:Внешние блоки программ при запуске Runtime exec

Process p = Runtime.getRuntime().exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" \"http://www.dr.dk/Forms/Published/PlaylistGen.aspx?qid=1316859&odp=true\" :sout=#std{access=udp,mux=ts,dst=127.0.0.1:63928}"); 

Если я выполнить вышеуказанную команду программа VLC будет запущена, и начнется операция потокового (она проходит через подключения, буферизации и затем потоковые фазы).

Когда команда исполняется Runtime exec (или запуском ProcessBuilder), программа vlc будет зависать, когда она достигнет конца фазы буферизации. Если все потоки в программе java заканчиваются/заканчиваются, программа vlc будет переходить на фазу потоковой передачи. Процесс java не завершится до тех пор, пока процесс vlc не будет закрыт, поэтому это поведение, очевидно, является результатом некоторой связи между процессами.

Попробовали выполнить команду косвенно, записав ее в .cmd-файл, а затем выполнив ее, но результат будет таким же.

Любые идеи о том, как я могу избежать внешнего висячего процесса?

+0

Желаете ли вы оставить процесс Java, работающий с открытым VLC, или завершить его и оставить процесс VLC запущенным? Я не уверен, что на самом деле происходит «соединение», поскольку процесс выполняется в своем собственном пространстве, но, возможно, есть некоторый элемент управления процессом, который поможет вам получить то, что вам нужно. – jheddings

ответ

5

Хм, я предполагаю, что VLC заполнил ваш буфер STDOUT и зависает в инструкции printf, потому что STDOUT ожидает, что этот буфер будет пуст.

Вам нужно получить поток для вывода процесса и прочитать его (даже если вы его отбросите).

Я рекомендую вам прочитать эту article

На 4-й странице является хорошим примером того, как читать потоки в потоках, чтобы ваш дочерний процесс не будет блокировать.

0

Этот сайт является фантастическим :). По какой-то причине подход, который, как я думал, уже был опробован, внезапно начал работать.

Проблема заключается в том, что vlc записывает на свой stdErrOut (который не отображается при выполнении в приглашении). Затем он блокируется, когда какой-то выходной буфер заполнен. Решение состоит в том, чтобы stdErr перенаправлялся на stdOut, а затем потоком был пуст входной поток объекта процесса.

Это, однако, не оптимальное решение, так как мне нужно много внешних процессов, и вы не можете делать неблокирующие операции ввода-вывода на своих входных потоках. Немного экспериментирует с наличием пустого чтения служебного диска таймера для ряда процессов. Другие предложения о том, как отменить процесс, чтобы избежать этой проблемы, очень приветствуются.

Смежные вопросы