2011-09-20 79 views
1

输出我已经有使用log4j的写在控制台输出的Java程序,而现在我想用另一个Java程序调用的第一个(子过程),并拦截其输出。 我使用的方法在http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4这个页面,部分代码如下图所示如何拦截子进程的父进程

class StreamRedirector extends Thread 
{ 
InputStream is; 

StreamRedirector(InputStream is) 
{ 
    this.is = is; 
} 

public void run() 
{ 
    try 
    { 
     BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
     String line=null; 
     while ((line = br.readLine()) != null) 
     { 
      System.out.println(line); 
     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 
} 
............. 
try 
    { 
     Process p = Runtime.getRuntime().exec("run.bat"); 

     StreamRedirector errSR = new StreamRedirector(p.getErrorStream()); 

     StreamRedirector outSR = new StreamRedirector(p.getInputStream()); 

     errSR.run(); 
     outSR.run(); 

     int exitVal = p.waitFor(); 
     System.out.println("Exit Value: " + exitVal); 
    } 

log4j config: 
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> 

    <param name="Target" value="System.out" /> 

    <layout class="org.apache.log4j.PatternLayout"> 

     <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%t] [%c{1}] %m%n" /> 
    </layout> 
</appender> 

我可以输出消息,而只是在“run.bat中”使用呼应XXX,而不是log4j的生成的消息。如果我跑“的run.bat”,我可以看到无论是在控制台输出。有没有办法,我也可以得到父进程log4j的输出?谢谢。

回答

1

StreamRedirector延伸Thread但你打电话runstart。这意味着,run获取调用同步,调用线程。这意味着在下面

errSR.run(); 
    outSR.run(); 

第二行不会执行,直到第一个完成。我想,如果错误流不会产生太大输出,则将最终完成。但那真的是你打算怎么做的?相反,如果程序使用log4j我劝你考虑SocketAppender抓住什么是从一个不同的进程写入的尝试

errSR.start(); 
    outSR.start(); 

EIDT:另一种方法是StreamRedirector扩展Runnable而不是Thread。然后调用代码更改为

Thread errorThread = new Thread(new StreamRedirector(p.getErrorStream())); 
.... 
errorThread.start(); 

这不会阻止你打电话errorThread.run(),但如果你调用它,然后它会立即返回(而不是阻塞,因为它目前如此)表明,什么是错。

+1

非常感谢血管,对不起,我作出这样一个愚蠢的错误:P – daniel

+0

Yould惊讶有多少人犯类似的错误。看看我上面的编辑如何避免它。 –