Question

Si je démarre un processus via Java Générateur de processus classe, j'ai un accès complet aux flux d'entrée, de sortie et d'erreur standard de ce processus en tant que Java InputStreams et OutputStreams.Cependant, je ne trouve pas de moyen de connecter de manière transparente ces flux à System.in, System.out, et System.err.

Il est possible d'utiliser redirectErrorStream() pour en avoir un seul InputStream qui contient la sortie standard et l'erreur standard du sous-processus, et il suffit de parcourir cela et de l'envoyer via ma sortie standard - mais je ne trouve pas de moyen de le faire et de laisser l'utilisateur taper dans le processus, comme il le pourrait si je utilisé le C system() appel.

Cela semble être possible dans Java SE 7 lors de sa sortie. Je me demande simplement s'il existe une solution de contournement maintenant.Points bonus si le résultat de isatty() dans le processus enfant effectue la redirection.

Était-ce utile?

La solution

Vous devrez copier le Processus flux de sortie, d'erreur et d'entrée vers les versions du système.La façon la plus simple de procéder consiste à utiliser le IOUtils classe du package Commons IO.Le méthode de copie cela semble être ce dont vous avez besoin.Les invocations de la méthode de copie devront se faire dans des threads distincts.

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

Autres conseils

Une variante de la réponse de John qui compile et ne nécessite pas l'utilisation de 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();
}

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

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

Mise en œuvre:

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

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top