繁体   English   中英

检测写入标准错误流

[英]Detecting write to standard error stream

是否有办法(无论它有多“ hacky”)检测何时写入Java的System.err 以便能够在何时以及何时发生逻辑时执行逻辑 —我目前正在使用Thread的自定义子类(我们称其为SwallowingThread ),该子类在Thread.run()实现中吞下了许多异常,其方式类似于以下代码:

public final class SwallowingThread extends Thread {

    ...

    @Override
    public void run() {
        ServerSocket socket = new ServerSocket(80, 100);
        try {
            Socket connected = socket.accept();
            // Do stuff with socket here
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

但是,在我的代码中,我希望能够处理在使用SwallowingThread实例时发生的UnknownHostExceptionIOException的情况; 发生这种情况后,没有办法检测到这种捕获和打印到标准错误吗? —我最初尝试编写UncaughtExceptionHandler来执行此操作,只是为了发现它没有捕获异常,因为它们被吞没了,而不是简单地被例如包装在RuntimeException并引发。

当然,解决此问题的一种“更好”的方法是重新编写类的逻辑,但是有没有无需触摸SwallowingThread就可以解决该问题的快捷方法吗?

您可以实现从PrintStream派生的自己的类(我称为DelegatingErrorPrintStream),该类会通知您是否有新输出,然后委托给System.err。现在您可以使用System.setErr(err)将YOUR DelegatingErrorPrintStream设置为System.err的输出流。 );

完整的示例,包括用法:

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

public class ErrorNotifierExample {
private static final class ErrorDelegatingPrintStream extends PrintStream {
    public ErrorDelegatingPrintStream(PrintStream defaultErr)
            throws FileNotFoundException, UnsupportedEncodingException {
        super(defaultErr);
    }

    @Override
    public void print(boolean b) {
        super.print(b);
        notifyListener(b);
    }

    @Override
    public void print(char c) {
        super.print(c);
        notifyListener(c);
    }

    @Override
    public void print(int i) {
        super.print(i);
        notifyListener(i);
    }

    @Override
    public void print(long l) {
        super.print(l);
        notifyListener(l);
    }

    @Override
    public void print(float f) {
        super.print(f);
        notifyListener(f);
    }

    @Override
    public void print(double d) {
        super.print(d);
        notifyListener(d);
    }

    @Override
    public void print(char[] s) {
        super.print(s);
        notifyListener(s);
    }

    @Override
    public void print(String s) {
        super.print(s);
        notifyListener(s);

    }

    @Override
    public void print(Object obj) {
        super.print(obj);
        notifyListener(obj);

    }

    @Override
    public PrintStream append(CharSequence csq, int start, int end) {
        notifyListener(csq); // TODO will need some special handling
        return super.append(csq, start, end);
    }

    private void notifyListener(Object string) {
        // TODO implement your handling here. System.out printing is just an
        // example.
        System.out.println(String.valueOf(string));
    }
}

public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
    ErrorDelegatingPrintStream errReplacement = new ErrorDelegatingPrintStream(System.err);
    System.setErr(errReplacement);

    System.err.println("TEST01");
    throw new RuntimeException("just a test output for ERROR handling");
}
}

正如几个人已经建议的那样,您可以使用自定义PrintStream

它将替换标准错误流,但也将其封装并在需要时调用它。

由于您对异常和堆栈跟踪感兴趣,因此重写print(String)应该就足够了( println(String)已经调用了此方法+ newLine() )。

流看起来像这样:

import java.io.PrintStream;

public class CustomPrintStream extends PrintStream {


    public CustomPrintStream(final PrintStream out) {

        super(out);

    }

    @Override
    public void print(final String s) {

        super.print(s);
        // some String is written to the error stream, Do something !

    }

}

您将以这种方式使用它,在应用程序开始时,只需调用

System.setErr(new CustomPrintStream(System.err));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM