web-dev-qa-db-fra.com

Rediriger la sortie Runtime.getRuntime (). Exec () avec System.setOut ();

J'ai un programme Test.Java:

import Java.io.*;

public class Test {
    public static void main(String[] args) throws Exception {
        System.setOut(new PrintStream(new FileOutputStream("test.txt")));
        System.out.println("HelloWorld1");
        Runtime.getRuntime().exec("echo HelloWorld2");
    }
}

Ceci est censé imprimer HelloWorld1 et HelloWorld2 dans le fichier text.txt. Cependant, lorsque je consulte le fichier, je ne vois que HelloWorld1.

  1. Où est passé HelloWorld2? At-il disparu dans l'air mince?

  2. Disons que je veux également rediriger HelloWorld2 vers test.txt. Je ne peux pas simplement ajouter un ">> test.txt" dans la commande car j'obtiendrai une erreur de fichier déjà ouvert. Alors, comment dois-je procéder?

23
Leo Izen

La sortie standard de Runtime.exec n'est pas envoyée automatiquement à la sortie standard de l'appelant.

Quelque chose comme cela devrait faire - avoir accès à la sortie standard du processus bifurqué, le lire et l'écrire. Notez que la sortie du processus forké est disponible pour le parent à l'aide de la méthode getInputStream() de l'instance Process.

public static void main(String[] args) throws Exception {
    System.setOut(new PrintStream(new FileOutputStream("test.txt")));
    System.out.println("HelloWorld1");

     try {
       String line;
       Process p = Runtime.getRuntime().exec( "echo HelloWorld2" );

       BufferedReader in = new BufferedReader(
               new InputStreamReader(p.getInputStream()) );
       while ((line = in.readLine()) != null) {
         System.out.println(line);
       }
       in.close();
     }
     catch (Exception e) {
       // ...
     }
}
40
martin clayton

Depuis JDK 1.5, il existe Java.lang.ProcessBuilder qui gère également les flux std et err. C'est en quelque sorte le remplacement de Java.lang.Runtime et vous devriez l'utiliser.

5
initialZero

System.out n'est PAS la sortie standard du nouveau processus que vous avez généré en appelant exec (). Si vous voulez voir le "HelloWorld2", vous devez obtenir le processus retourné à partir de l'appel exec (), puis appeler getOutputStream () à partir de cela.

2
rfeak

Un moyen plus simple d'atteindre l'objectif:

    ProcessBuilder builder = new ProcessBuilder("hostname");
    Process process = builder.start();
    Scanner in = new Scanner(process.getInputStream());
    System.out.println(in.nextLine()); // or use iterator for multilined output
0
fg78nc