2014-05-20 18 views
2

我正在使用inheritIO()將輸出從我的程序中的子進程重定向到System.outSystem.err,並輸入到System.inProcessBuilder.inheritIO()發送輸出到錯誤的位置

這些都是由System.setOut()重定向和類似:

// Reassign System IO 
System.setIn(cpanel.getConsole().getInputStream()); 
System.setOut(new PrintStream(cpanel.getConsole().getOutputStream())); 
System.setErr(new PrintStream(cpanel.getConsole().getOutputStream())); 

然而,當我運行過程:

String[] fullargs = new String[sargs.length+4]; 
fullargs[0] = "java"; 
fullargs[1] = "-classpath"; // Runtime classpath option. 
fullargs[2] = cpath;   // Specify the classpath. 
fullargs[3] = mname;   // Specify class to run. 

for(int i=0; i<sargs.length; i++) 
{ 
    fullargs[i+4] = sargs[i]; // Put together arguments. 
} 

ProcessBuilder proc = new ProcessBuilder() 
          .inheritIO() 
          .command(fullargs); 


try 
{ 
    System.out.println("RUNNING..."); 
    proc.start(); 
} 
catch(IOException ioe) 
{ 
    JOptionPane.showMessageDialog(null, 
     "There was a system error invoking this program.", 
     "ERROR", 
     JOptionPane.ERROR_MESSAGE); 
} 

它重定向到什麼以前是System.out等,而不是什麼他們已被重定向到。

如果我註釋掉inheritIO()一行,輸出將會丟失,並且不會出現在任何地方。使用inheritIO()它會轉到父進程的標準控制檯而不是重定向的控制檯。我打印「RUNNING」的行會轉到正確的重定向位置。換句話說,如果我沒有重定向父進程的輸出流,那麼inheritIO()正在執行它應該是。它將進入父進程的舊控制檯。

我不知道爲什麼會發生這種情況,我在這裏拉我的頭髮。我已經看到inheritIO()在Windows中不起作用,但在Mac OS和Linux上這個問題是一樣的。我使用的Java 7

+0

這個問題可以給你一個線索嗎? http://stackoverflow.com/questions/14165517/processbuilder-forwarding-stdout-and-stderr-of-started-processes-without-blocki – fluminis

+0

@fluminis其中的解決方案是Java 6和以前的。 Java 7及以上版本中的'inheritIO()'函數旨在自動執行此操作。 –

回答

0

請注意這裏我的答案:https://stackoverflow.com/a/32350856/5226711

適用於你的問題,這意味着你可以使用StreamGobbler的優化版本改編提出了https://stackoverflow.com/a/14165567/5226711

private class StreamGobbler extends Thread { 
    private InputStream in; 
    private PrintStream out; 

    private StreamGobbler(InputStream in, PrintStream out) { 
     this.in = in; 
     this.out = out; 
    } 

    @Override 
    public void run() { 
     try { 
      BufferedReader input = new BufferedReader(new InputStreamReader(in)); 
      String line = null; 
      while ((line = input.readLine()) != null) 
       out.println(line); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

而且像這樣使用它:

String[] fullargs = new String[sargs.length+4]; 
fullargs[0] = "java"; 
fullargs[1] = "-classpath"; // Runtime classpath option. 
fullargs[2] = cpath;   // Specify the classpath. 
fullargs[3] = mname;   // Specify class to run. 

for(int i=0; i<sargs.length; i++) 
{ 
    fullargs[i+4] = sargs[i]; // Put together arguments. 
} 

ProcessBuilder pb = new ProcessBuilder().command(fullargs); 

try 
{ 
    System.out.println("RUNNING..."); 
    Process p = pb.start(); 
    StreamGobbler pOut = new StreamGobbler(p.getInputStream(), new PrintStream(cpanel.getConsole().getOutputStream())); 
    StreamGobbler pErr = new StreamGobbler(p.getErrorStream(), new PrintStream(cpanel.getConsole().getOutputStream())); 
    pOut.start(); 
    pErr.start(); 
} 
catch(IOException ioe) 
{ 
    JOptionPane.showMessageDialog(null, 
     "There was a system error invoking this program.", 
     "ERROR", 
     JOptionPane.ERROR_MESSAGE); 
} 

我的示例中不包括重定向孩子的stdin。