2010-09-20 11 views
10

Ho scritto il codice java qui sotto, che esegue un altro programma java chiamato "Newsworthy_RB".Come fare un programma java per stampare entrambe le istruzioni out.println() e err.println()?

Newsworthy_RB.java contiene sia la System.out.printlln (dichiarazioni System.err.println()) e.

voglio entrambe le uscite da stampare nella console prompt dei comandi.

Cosa si deve fare inorder per ottenere lo stesso.

Il programma qui sotto stamperà solo l'out.println) dichiarazioni (e non l'err.println() dichiarazioni.

Gentilmente vorrei sapere se il codice qui sotto funzionerà come mi aspetto?

command = "java -cp .:../sqljdbc.jar SetHash Newsworthy_RB"; 
Process child1 = Runtime.getRuntime().exec(command); 
InputStream in1 = child1.getErrorStream(); 
InputStream in2 = child2.getInputStream(); 
while ((c = in1.read()) != -1 || (c = in2.read()) != -1) { 
     System.out.print((char)c); 
    } 

risposta

14

Innanzi tutto, il modo preferito di avviare programmi esterni è attraverso ProcessBuilder. Si è anche menzionato in the docs for Runtime:

ProcessBuilder.start() è ora il modo preferito per iniziare un processo con un ambiente modificato.

In ProcessBuilder di avere un metodo molto conveniente chiamato redirectErrorStream: proprietà redirectErrorStream

Imposta questo costruttore processo.

Se questa proprietà è vera, allora qualsiasi output di errore generato dal sottoprocessi successivamente iniziate da inizio di questo oggetto() metodo verrà fusa con lo standard output, in modo che entrambi possano essere letto utilizzando il Process.getInputStream () metodo. Ciò semplifica la correlazione dei messaggi di errore con l'output corrispondente. Il valore iniziale è falso.

un esempio completo di come l'uscita sia standard error e standard output:

import java.io.*; 

public class Test { 
    public static void main(String... args) throws IOException { 

     ProcessBuilder pb = 
       new ProcessBuilder("java", "-cp", "yourClassPath", "HelloWorld"); 

     pb.redirectErrorStream(true); 
     Process proc = pb.start(); 

     Reader reader = new InputStreamReader(proc.getInputStream()); 
     int ch; 
     while ((ch = reader.read()) != -1) 
      System.out.print((char) ch); 
     reader.close(); 
    } 
} 

risposta alla vostra aggiornamento: No, il codice con

while ((c = in1.read()) != -1 || (c = in2.read()) != -1) 

non lo farà lavoro, dal momento che read() è un metodo di blocco e hai solo un thread. L'unica opzione è usare un thread per input-stream o, (preferibilmente) unire i due input-stream in uno, usando ProcessBuilder.redirectErrorStream.

+0

Adoro il tipo di spiegazione. Grazie mille per la tua risposta. Ma per il momento, gentilmente fammi sapere se la modifica che ho fatto nella mia domanda funzionerà o no? – LGAP

+0

Implementerò sicuramente i concetti di ProcessBuilder nelle mie future procedure. – LGAP

+0

Fammi sapere anche 'ProcessBuilder pb = new ProcessBuilder (" java "," HelloWorld ");' come menzionare il classpath del programma in questa istruzione? – LGAP

10

È necessario reindirizzare l'output di entrambi i flussi in thread separati. Codice di esempio da here:

Process p = Runtime.getRuntime().exec(cmd.array()); 
copyInThread(p.getInputStream(), System.out); 
copyInThread(p.getErrorStream(), System.err); 
p.waitFor(); 
return p.exitValue(); 

private void copyInThread(final InputStream in, final OutputStream out) { 
    new Thread() { 
     public void run() { 
      try { 
       while (true) { 
        int x = in.read(); 
        if (x < 0) { 
         return; 
        } 
        if (out != null) { 
         out.write(x); 
        } 
       } 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 
    } .start(); 
} 
+0

Grazie per la tua risposta Mueller. Ho aggiornato la mia domanda.Per favore fatemi sapere che funzionerà o no? – LGAP

+3

Dai documenti di 'Runtime':" ProcessBuilder.start() è ora il modo preferito per avviare un processo con un ambiente modificato. ". Raccomando di usare 'ProcessBuilder.redirectErrorStream'. (Vedi la mia risposta.) – aioobe

+0

@aioobe: Hai ragione! Non sapevo di ProcessBuilder. –

1

Ci sono due metodi nell'oggetto Processo: getErrorStream e getInputStream. Attualmente, il tuo programma ne sta ascoltando solo uno. Lo vorresti per ascoltare entrambi.

Problemi correlati