2010-11-20 15 views
6

Muszę uruchomić zewnętrzny plik wykonywalny w taki sposób, aby użytkownik mógł wchodzić w interakcje z uruchomionym programem.Uruchom zewnętrzny plik wykonywalny z kodu Java za pomocą przekierowania strumieni

Na przykład w systemie OpenSuse Linux znajduje się menedżer pakietów - Zypper. Możesz uruchomić zyppera w trybie poleceń i przekazać mu polecenia takie jak instalowanie, aktualizowanie, usuwanie itp.

Chciałbym uruchomić go z kodu Java w sposób użytkownik może wchodzić w interakcje z nim: polecenia wejściowe i zobaczyć wyniki i błędy programu, który rozpoczął.

Oto kod Java Próbuję użyć:

public static void main(String[] args) throws IOException, InterruptedException { 
    Process proc = java.lang.Runtime.getRuntime().exec("zypper shell"); 

    InputStream stderr = proc.getInputStream(); 
    InputStreamReader isr = new InputStreamReader(stderr); 
    BufferedReader br = new BufferedReader(isr); 
    String line = null; 
    char ch; 

    while ((ch = (char)br.read()) != -1) 
     System.out.print(ch); 

    int exitVal = proc.waitFor(); 
    System.out.println("Process exitValue: " + exitVal); 
} 

Ale niestety widzę tylko to wyjście:

zypper> 

ale bez względu na to, co piszę, mój wkład nie wpływa program, który został uruchomiony. Jak mogę zrobić, co chcę?

Odpowiedz

2

Musisz dostać strumień wyjściowy, aby napisać do procesu:

OutputStream out = proc.getOuptutStream(); 

Ten strumień wyjściowy jest wyprowadzony do standardowego wejścia strumienia procesu, więc można po prostu napisać do niego (być może chcesz najpierw go zawinąć w pliku PrintWriter), a dane zostaną przesłane do procesu "stdin.

Należy pamiętać, że może być również wygodnie uzyskać strumień błędów (proc.getErrorStream), aby odczytać dane wyjściowe błędu zapisywane przez proces na jego stderr.

odniesienia API:

+0

Dziękuję za odpowiedź. To pomogło! –

0

wydaje się, że konwersja wewnątrz chwilę stan zawodzi w przykładzie, to wydaje się działać lepiej (nie uruchamiać Suse więc nie mam próbował z Zypperem):

public static void main(String[] args) throws IOException, InterruptedException 
{ 
    //Process proc = java.lang.Runtime.getRuntime().exec("zypper shell"); 
    Process proc = java.lang.Runtime.getRuntime().exec("ping -t localhost"); 

    InputStream stderr = proc.getInputStream(); 
    InputStreamReader isr = new InputStreamReader(stderr); 
    BufferedReader br = new BufferedReader(isr); 

    int i; 
    while ((i = br.read()) != -1) 
    { 
     System.out.print((char) i); 
    } 

    int exitVal = proc.waitFor(); 
    System.out.println("Process exitValue: " + exitVal); 
} 
0

Niedawno zapakowałem kompilator Google Closure do pliku .jar, który jest wyodrębniany i wykorzystywany w procesie. Ten kompilator rozmawia tylko przez System.in/out/err. W łączeniu rurek jest duże "gotcha", o którym krótko wspomina się w Process javadoc.

„... brak niezwłocznie napisać strumień wejściowy lub odczytać strumienia wyjściowego z podproces może spowodować podproces do blokowania, a nawet impasu”.

W systemie Mac OS X bufor ma wartość 16k, a jeśli go nie przeczyta się natychmiast zgodnie z sugestią, zakleszczenia procesów. Moje jedyne rozwiązanie tego problemu ATM, jest dość nieprzyjemnie zajęte czekać.

https://github.com/algesten/googccwrap/blob/master/src/main/java/googccwrap/GoogleClosureCompilerWrapper.java

Powiązane problemy