2010-11-20 38 views
6

Je dois démarrer l'exécutable externe de telle sorte que l'utilisateur puisse interagir avec le programme qui vient d'être démarré.Démarrage de l'exécutable externe à partir du code Java avec la redirection des flux

Par exemple, dans OpenSuse Linux, il existe un gestionnaire de paquets - Zypper. Vous pouvez lancer zypper en mode commande et lui donner des commandes comme installer, mettre à jour, supprimer, etc. Je voudrais l'exécuter à partir du code Java d'une manière dont l'utilisateur pourrait interagir avec lui: entrer des commandes et voir la sortie et les erreurs du programme qu'il a démarré.

Voici un code Java j'ai essayé d'utiliser:

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

Mais malheureusement je ne peux voir sa sortie:

zypper> 

mais peu importe ce que j'écris, mon entrée ne touche pas programme qui a été démarré. Comment puis-je faire ce que je veux?

Répondre

2

Vous devez obtenir un flux de sortie afin d'écrire au processus:

OutputStream out = proc.getOuptutStream(); 

Ce flux de sortie est canalisé dans le flux d'entrée standard du processus, de sorte que vous pouvez simplement y écrire (peut-être vous voulez envelopper dans un PrintWriter d'abord) et les données seront envoyées au processus 'stdin.

Notez qu'il peut également être pratique d'obtenir le flux d'erreurs (proc.getErrorStream) afin de lire toute sortie d'erreur que le processus écrit dans son chemin d'accès d'erreur.

référence API:

+0

Nous vous remercions de votre réponse. Cela a aidé! –

0

On dirait que la conversion à l'intérieur de l'état tout échoue dans votre exemple, cela semble fonctionner mieux (je ne pas courir Suse donc j'ai pas essayé avec 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

J'ai récemment enveloppé Google Closure Compiler dans un fichier .jar qui est extrait et utilisé dans un processus. Ce compilateur ne parle que via System.in/out/err. Il y a un gros "getcha" dans la connexion des tuyaux, ce qui est brièvement mentionné dans le processus javadoc.

« ... non écrire rapidement le flux d'entrée ou lire le flux de sortie du sous-processus peut entraîner la pour bloquer le sous-processus, et même impasse . »

Sous Mac OS X, le tampon est de 16 Ko, et si vous ne le lisez pas rapidement, comme suggéré, le processus est bloqué. Ma seule solution à ce problème ATM, est une attente occupée plutôt désagréable.

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