27 votes

Démarrage d'un processus avec stdin / stdout / stderr hérité dans Java 6

Si je commence un processus via Java ProcessBuilder classe, j'ai plein accès à ce processus est la norme dans, standard, et l'erreur-type de cours d'eau comme Java InputStreams et OutputStreams. Cependant, je ne peux pas trouver un moyen de se connecter de façon transparente ces flux d' System.in, System.out, et System.err.

Il est possible d'utiliser redirectErrorStream() pour obtenir un seul InputStream qui contient les sous-processus du standard et d'erreur standard, et juste faire une boucle par qui et envoyer par mon standard, mais je ne peux pas trouver un moyen de le faire et de laisser le type d'utilisateur dans le processus, car il ou elle pourrait, si j'ai utilisé le C system() appel.

Cela semble être possible en Java SE 7 lors de sa sortie-je me demandais simplement si il y a une solution maintenant. Les points de Bonus si le résultat de l' isatty() dans le processus de l'enfant conduit à travers la redirection.

15voto

John Meagher Points 6734

Vous devez copier le Processus de sortie, err, et les flux d'entrée pour les versions de Système. La façon la plus simple pour cela est d'utiliser la IOUtils classe à partir de l'Commons IO paquet. La méthode de copie semble être ce dont vous avez besoin. La copie des invocations de méthode doivent être dans des threads séparés.

Voici le code de base:

// Assume you already have a processBuilder all configured and ready to go
final Process process = processBuilder.start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(process.getOutputStream(), System.out);
} } ).start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(process.getErrorStream(), System.err);
} } ).start();
new Thread(new Runnable() {public void run() {
  IOUtils.copy(System.in, process.getInputStream());
} } ).start();

13voto

Eelco Points 1411

Une variation de la réponse de John qui compile et ne vous oblige pas à utiliser Commons IO:

 private static void pipeOutput(Process process) {
    pipe(process.getErrorStream(), System.err);
    pipe(process.getInputStream(), System.out);
}

private static void pipe(final InputStream src, final PrintStream dest) {
    new Thread(new Runnable() {
        public void run() {
            try {
                byte[] buffer = new byte[1024];
                for (int n = 0; n != -1; n = src.read(buffer)) {
                    dest.write(buffer, 0, n);
                }
            } catch (IOException e) { // just exit
            }
        }
    }).start();
}
 

3voto

claude Points 31

Pour System.in utilisez les pipein() au lieu de pipe()

 pipein(System.in, p.getOutputStream());
 

La mise en oeuvre:

 private static void pipein(final InputStream src, final OutputStream dest) {

    new Thread(new Runnable() {
        public void run() {
            try {
               int ret = -1;
               while ((ret = System.in.read()) != -1) {
                  dest.write(ret);
                  dest.flush();
               }
            } catch (IOException e) { // just exit
            }
        }
    }).start();

}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X