Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 即使在设置System.setErr()之后,也无法使用自定义PrintStream打印错误_Java_Multithreading_Console - Fatal编程技术网

Java 即使在设置System.setErr()之后,也无法使用自定义PrintStream打印错误

Java 即使在设置System.setErr()之后,也无法使用自定义PrintStream打印错误,java,multithreading,console,Java,Multithreading,Console,基本上,我想让console做两件事: 我想让控制台给错误和一般信息消息涂上颜色(这些错误是红色的,其他的都是绿色的) 我想将所有控制台消息保存到日志文件中 因此,我创建了一个打印流,看起来像这样: public static class GeneralStream extends PrintStream { public GeneralStream(OutputStream out) { super(out); } @Override pub

基本上,我想让console做两件事:

  • 我想让控制台给错误和一般信息消息涂上颜色(这些错误是红色的,其他的都是绿色的)
  • 我想将所有控制台消息保存到日志文件中
  • 因此,我创建了一个打印流,看起来像这样:

    public static class GeneralStream extends PrintStream {
    
        public GeneralStream(OutputStream out) {
            super(out);
        }
    
        @Override
        public void println(String string) {
            String time = DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now());
    
            String output = "["+time+"] ["+type.n()+"] "+string;
            Logs.logToFile(output);
            
            String coloredOutput = ANSI_RESET+ANSI_WHITE+"["+ANSI_CYAN+time+ANSI_WHITE+"] "+
                    ANSI_WHITE+"["+ANSI_RESET+type.c()+type.n()+ANSI_WHITE+"] "+type.c()+string+ANSI_RESET;
            super.println(coloredOutput);
        }
    }
    
    太好了。然后,我在程序开始时使用以下命令将此打印流设置为默认打印流:

    // Set console output settings
        System.setOut(new Console.GeneralStream(System.out));
        System.setErr(new Console.GeneraStream(System.err));
    
    太棒了。最后,在完成System.out.println(“helloworld”)之后,我得到了我期望的结果。我的留言是彩色的。它们被记录到一个文件中。伟大的事实上,即使我执行System.err.println(“Error!”),我仍然会得到预期的结果但是,“自动”异常不会通过系统打印。我设置的错误

    以下是一个例子:

    // Set console output settings
        System.setOut(new Console.GeneralStream(System.out));
        System.setErr(new Console.ErrorStream(System.err));
    
        System.out.println("Hello world!");
        System.err.println("Printing an error!");
    
        // Real exception (NPE)
        Integer nullInteger = null;
        System.out.println(nullInteger.toString()); // won't print and will produce a NullPointException
    
    结果如下:


    因此,我的问题是如何为这样的错误设置自定义打印流,以便将它们记录到文件中(最好遵循我的自定义消息格式)。

    如果深入研究Throwable类如何打印堆栈跟踪,您将看到它使用
    println(Object)
    方法,因此,您需要将此方法添加到自定义ErrorStream类中:

    @Override
    public void println(Object object) {
        println(String.valueOf(object));
    }
    
    即使如此,您也可能希望更改“未捕获异常处理程序”以更改其记录异常的方式。默认的处理程序调用第一个代码<代码> St.Er.Prime<代码>,输出线程“{thordNe}}”<代码> >“代码> >可投掷。PrrtStActTrace< /Cord>,这样您就可以在消息中间得到时间戳和其他东西。例如:

        Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
            System.err.println("Uncaught exception in thread " + thread.getName());
            throwable.printStackTrace(System.err);
        });
    

    如果程序中有多个线程呢?您是否必须对每个线程都执行此操作?JVM只有一个全局“默认未捕获异常处理程序”这就是为什么
    Thread.setDefaultUncaughtExceptionHandler
    是静态的-但是如果您有带有自定义异常处理程序的线程或线程组,您必须逐个检查它们的功能非常感谢您的帮助。非常感谢!