如何在父进程中拦截子进程的输出
我已经有一个使用 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”使用 echo XXX ,而不是 log4j 生成的消息。如果我运行“run.bat”,我可以在控制台中看到两个输出。有没有办法让我也可以在父进程中获取 log4j 输出?谢谢。
I already have a java program using log4j to write output on console, while now I want use another java program to invoke the first one(sub-process) and intercept its output.
I use the method in this page http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4, some codes like below
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>
I can get the output message, but just in "run.bat" using echo XXX , not the message generated by log4j. If I run "run.bat", I can see both the output in console. Is there a way that I can also get the log4j output in parent process? thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
StreamRedirector
扩展了Thread
,但您调用的是run
而不是start
。这意味着run
在调用线程中被同步调用。这意味着下面的第二行在第一行完成之前不会执行。我想如果错误流不会产生太多输出,那么它最终会完成。但这真的是您打算做的吗?相反,请尝试
如果程序正在使用
log4j
,我强烈建议您考虑SocketAppender
来获取从不同进程写入的内容。EIDT:另一种方法是让
StreamRedirector
扩展Runnable
而不是Thread
。然后调用代码更改为This won't Prevent you from Calling
errorThread.run()
但如果你确实调用它,那么它将立即返回(而不是像当前那样阻塞),表明某些事情正在发生错误的。The
StreamRedirector
extendsThread
but you callrun
notstart
. This means thatrun
is getting called synchronously, in the calling thread. Which means that in the followingThe second line does not execute until the first completes. I guess if the error stream does not produce much output then it will eventually complete. But is that really what you intend to do? Instead try
If the program is using
log4j
I urge you to considerSocketAppender
to grab what is written to it from a different process.EIDT: Another approach is for
StreamRedirector
to extendRunnable
instead ofThread
. The calling code then changes toThis won't prevent you from calling
errorThread.run()
but if you do call it then it will return immediately (instead of blocking as it currently does) suggesting that something is wrong.