2010-11-20 18 views
6

Necesito iniciar un archivo ejecutable externo de tal manera que el usuario pueda interactuar con el programa que acaba de iniciar.Iniciar el ejecutable externo desde el código de Java con la redirección de secuencias

Por ejemplo, en OpenSuse Linux hay un administrador de paquetes - Zypper. Puede iniciar zypper en modo comando y asignarle comandos como instalar, actualizar, eliminar, etc.

Me gustaría ejecutarlo desde el código de Java de una manera que el usuario pueda interactuar con él: comandos de entrada y ver resultados y errores del programa que comenzó.

Aquí hay un código Java Traté de usar:

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); 
} 

Pero por desgracia sólo se puede ver que es la salida:

zypper> 

pero no importa lo que escribo, mi entrada no afecta programa que se inició. ¿Cómo puedo hacer lo que quiero?

Respuesta

2

que necesita para obtener un flujo de salida con el fin de escribir en el proceso:

OutputStream out = proc.getOuptutStream(); 

Esta corriente de salida se canaliza en el flujo de entrada estándar del proceso, lo que sólo puede escribir en él (tal vez desea envolverlo en un PrintWriter primero) y los datos se enviarán al proceso 'stdin'.

Tenga en cuenta que también podría ser conveniente obtener la secuencia de error (proc.getErrorStream) para leer cualquier salida de error que el proceso escriba en su stderr.

referencia de la API:

+0

Gracias por su respuesta. ¡Eso ayudó! –

0

parece que la conversión interior al mismo tiempo condición falla en su ejemplo, esto parece funcionar mejor (no correr Suse así que no tengo intentado con Zypper):

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

Recientemente envolví Google Closure Compiler en un archivo .jar que se extrae y utiliza en un proceso. Este compilador solo habla a través de System.in/out/err. Hay un gran "problema" al conectar las tuberías, que se menciona brevemente en el Proceso javadoc.

"... el fracaso de escribir rápidamente el flujo de entrada o leer el flujo de salida del subproceso puede causar la subproceso para bloquear, e incluso punto muerto."

En Mac OS X, el almacenamiento intermedio es 16k, y si no lo lee rápidamente como se sugiere, el proceso se traba. Mi única solución para este problema ATM, es una espera ocupada bastante desagradable.

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

Cuestiones relacionadas