如何在父进程中拦截子进程的输出

发布于 2024-12-05 08:13:40 字数 1567 浏览 0 评论 0原文

我已经有一个使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没有 2024-12-12 08:13:40

StreamRedirector 扩展了 Thread,但您调用的是 run 而不是 start。这意味着 run 在调用线程中被同步调用。这意味着下面的

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

第二行在第一行完成之前不会执行。我想如果错误流不会产生太多输出,那么它最终会完成。但这真的是您打算做的吗?相反,请尝试

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

如果程序正在使用 log4j,我强烈建议您考虑 SocketAppender 来获取从不同进程写入的内容。

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

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

This won't Prevent you from Calling errorThread.run() 但如果你确实调用它,那么它将立即返回(而不是像当前那样阻塞),表明某些事情正在发生错误的。

The StreamRedirector extends Thread but you call run not start. This means that run is getting called synchronously, in the calling thread. Which means that in the following

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

The 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

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

If the program is using log4j I urge you to consider SocketAppender to grab what is written to it from a different process.

EIDT: Another approach is for StreamRedirector to extend Runnable instead of Thread. The calling code then changes to

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

This 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文