Domanda

Se avvio un processo tramite Java's ProcessBuilder class, ho pieno accesso ai flussi di ingresso standard, uscita standard ed errori standard di quel processo come Java InputStreams E OutputStreams.Tuttavia, non riesco a trovare un modo per connettere perfettamente tali flussi a System.in, System.out, E System.err.

È possibile utilizzare redirectErrorStream() per ottenerne uno singolo InputStream che contiene lo standard out e l'errore standard del sottoprocesso, e basta scorrere questo e inviarlo tramite il mio standard out, ma non riesco a trovare un modo per farlo e lasciare che l'utente digiti nel processo, come potrebbe se io utilizzato il C system() chiamata.

Questo sembra essere possibile in Java SE 7 quando uscirà: mi chiedo solo se ora ci sia una soluzione alternativa.Punti bonus se il risultato di isatty() nel processo figlio esegue il reindirizzamento.

È stato utile?

Soluzione

Dovrai copiare il file Processi out, err e flussi di input nelle versioni di sistema.Il modo più semplice per farlo è utilizzare il file IOUtils classe dal pacchetto Commons IO.IL metodo di copia sembra essere quello di cui hai bisogno.Le chiamate al metodo di copia dovranno trovarsi in thread separati.

Ecco il codice 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();

Altri suggerimenti

Una variazione della risposta di John che compila e non richiede l'utilizzo di 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();
}

Per System.in utilizza il seguente pipein() invece di pipe()

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

Implementazione:

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

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top