2010-10-14 15 views
25

Próbuję pobrać OutputStream z Process zainicjowaną przez exec() do konsoli. Jak to zrobić?Drukowanie Runtime exec() OutputStream na konsolę

Oto niepełna Kod:

import java.io.BufferedReader; 
import java.io.File; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.io.PrintStream; 
import java.io.Reader; 

public class RuntimeTests 
{ 
    public static void main(String[] args) 
    { 
     File path = new File("C:\\Dir\\Dir2"); 
     String command = "cmd /c dir"; 
     Reader rdr = null; 
     PrintStream prtStrm = System.out; 
     try 
     { 
      Runtime terminal = Runtime.getRuntime(); 

      OutputStream rtm = terminal.exec(command, null, path).getOutputStream(); 
      prtStrm = new PrintStream(rtm); 
      prtStrm.println(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

Odpowiedz

2

Trzeba rozpocząć nowy wątek, który będzie czytać terminala strumień wyjściowy i skopiuj go do konsoli, po wywołaniu process.waitFor()

+3

Na każdy przychodzi na to pytanie w dzisiejszych czasach: przewijanie w dół, tam jest lepszy Odpowiedź poniżej – forresthopkinsa

32

I że to jest to, czego szukasz:

String line; 
    Process p = Runtime.getRuntime().exec(...); 
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    while ((line = input.readLine()) != null) { 
    System.out.println(line); 
    } 
    input.close(); 
+1

mam pytanie twoje rozwiązanie: Czy nie ma potrzeby korzystania z metody process.waitFor()? Działa również bez, ale dlaczego? Czy InputStreamReader czeka na zakończenie strumienia? –

+2

Tak, API: _Jeśli żaden bajt nie jest dostępny, ponieważ został osiągnięty koniec strumienia, zwracana jest wartość -1. Ta metoda blokuje dostęp do danych wejściowych, wykrywa koniec strumienia lub zostaje zgłoszony wyjątek. –

+0

dodaje 'redirectErrorStream (true)' dla kompletności. –

74

niedawno wpadłem na ten problem i po prostu chciałem wspomnieć, że od Java 7, process builder api został rozszerzony. Problem ten może być rozwiązany teraz z:

ProcessBuilder pb = new ProcessBuilder("yourcommand"); 
pb.redirectOutput(Redirect.INHERIT); 
pb.redirectError(Redirect.INHERIT); 
Process p = pb.start(); 

Mam nadzieję, że to pomoże :)

+2

Idealna i elegancka odpowiedź. Jeśli możesz korzystać z Java 7, jest to absolutnie droga. – Shane

+0

To jest najlepsza odpowiedź, mimo że są dobre, ale zawsze staraj się używać narzędzi dostępnych domyślnie w przyborniku Java. Java 7/8 jest niezwykle wydajnym i potężnym językiem - z ciągle rozwijającym się, ale wydajnym zestawem narzędzi. – DtechNet

11

I w obliczu podobnego problemu i używam następujący kod.

Process p = Runtime.getRuntime().exec("....."); 
p.waitFor(); 

String line; 

BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
while((line = error.readLine()) != null){ 
    System.out.println(line); 
} 
error.close(); 

BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
while((line=input.readLine()) != null){ 
    System.out.println(line); 
} 

input.close(); 

OutputStream outputStream = p.getOutputStream(); 
PrintStream printStream = new PrintStream(outputStream); 
printStream.println(); 
printStream.flush(); 
printStream.close(); 
2

Spróbuj VerboseProcess z jcabi-log:

String output = new VerboseProcess(new ProcessBuilder("foo.bat")).stdout(); 

Klasa uruchamia wątek tła, słucha strumienia wyjściowego, a dzienniki IT.

0

Jeśli można użyć org.apache.commons.io.IOUTils ze świetlicy-IO,

System.out.println(IOUtils.toString(process.getInputStream())); 
System.err.println(IOUtils.toString(process.getErrorStream())); 
Powiązane problemy