System.out.println/System.err.println无法正常工作,附测试代码求助
排查
System.err.println失效问题 咱们先从你给出的代码片段里揪几个关键问题,这些大概率是导致输出不生效的原因:
1. PrintStream 未开启自动刷新
你创建PrintStream时没开启自动刷新,默认情况下只有特定方法(比如println)才会触发缓冲区刷新,但多线程场景下,缓冲区可能攒着内容没写入文件,甚至程序结束前都没完成刷新。修改构造方法,加上第二个参数true开启自动刷新:
out = new PrintStream(new FileOutputStream("C:\\pathToFile\\test2_output.txt"), true);
2. 未校验输出流是否初始化成功
如果FileOutputStream因为路径不存在、无写入权限等原因初始化失败,out会是null,这时候调用System.setErr(out)会把标准错误流设为null,后续所有System.err.println都会失效。要先判断out是否有效再设置:
if (out != null) { System.setErr(out); } else { System.err.println("无法创建输出文件流,将使用默认控制台输出"); }
3. 资源未正确关闭
你没有关闭PrintStream和FileOutputStream,这会导致缓冲区里的剩余内容无法全部写入文件。推荐用try-with-resources语法自动管理资源,避免手动关闭的遗漏:
try (PrintStream out = new PrintStream(new FileOutputStream("C:\\pathToFile\\test2_output.txt"), true)) { System.setErr(out); // 后续线程相关代码放在这里 } catch (FileNotFoundException e1) { System.err.println(e1); }
4. 测试方法提前终止
你的测试方法启动线程后,可能在线程执行完成前就结束了,导致JVM直接终止,输出还没来得及写入文件。需要在测试方法最后等待所有线程执行完毕,比如用Thread.join(),或者换成CountDownLatch更适配这种场景:
final CountDownLatch latch = new CountDownLatch(2); // 假设启动2个工作线程 Thread thread1 = new Thread(() -> { try { latch.await(); // 等待所有线程就绪 System.err.println("线程1执行输出"); } catch (InterruptedException e) { System.err.println(e); } finally { latch.countDown(); } }); thread1.start(); // 启动第二个线程(逻辑类似) Thread thread2 = new Thread(() -> { try { latch.await(); System.err.println("线程2执行输出"); } catch (InterruptedException e) { System.err.println(e); } finally { latch.countDown(); } }); thread2.start(); latch.countDown(); // 放行所有线程 latch.await(); // 测试方法等待所有线程完成
额外检查点
- 确认
C:\\pathToFile\\这个路径确实存在,并且程序有该目录的写入权限; - 检查代码片段里未写完的
System.err.printl...是否补全为正确的System.err.println()调用。
按照上面的点调整后,应该就能解决输出无法正常写入文件的问题了。
内容的提问来源于stack exchange,提问作者saferJo
相关产品推荐
相关产品推荐

