资讯动态

System2.java

发布时间:2026/8/30 10:02:40 来源:尧图企业网站定制
System.out.println(““) System.err.println(““)package further.util; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; /** * 控制台同步输出项目扩展与 {link java.lang.System} 不同包名避免替 JDK 引导类。 * p * strong顺序/strongEclipse 等对 stdout / stderr strong两条管道分别缓冲/strong即使 JVM 里加锁、逐行 flush * 控制台仍常出现「先整块黑字、再整块红字」与源码交替调用顺序不一致——这在 IDE 侧无法仅靠 Java 根治。 * 要保证strong显示顺序与调用顺序一致/strong只能strong合并为一条管道/strong只写 {link FileDescriptor#out}见 {link #installOrderedConsole()}。 * /p * p * strong红色/strongIDE 的红字来自strong真实 stderrfd2/strong见 {link #installDualFileDescriptorConsole()} * 与「合并管道保顺序」二者在 Eclipse 内置控制台里strong不可兼得/strong。合并模式下 {link Kind#ERR} 时默认加 * {code [stderr] } 前缀区分错误语义若控制台支持 ANSI可加 {code -Dsyncconsole.ansiErrtrue} 尝试红色转义部分 Eclipse 版本仍不会着色。 * /p * * author ZengWenFeng * mobile 13805029595 * email 117791303qq.com * date 2026.05.08 */ public final class System2 { /** * 打印目标标准输出 / 标准错误语义用于 {link #println(Kind, String)} 第一个参数。 */ public enum Kind { /** 标准输出 */ OUT, /** 标准错误 */ ERR } /** 与 {link Kind#OUT} 相同便于书写 {code System2.println(System2.OUT, ...)} */ public static final Kind OUT Kind.OUT; /** 与 {link Kind#ERR} 相同 */ public static final Kind ERR Kind.ERR; private static final Object CONSOLE_LOCK new Object(); private static final String STDERR_PREFIX [stderr] ; private static final String ANSI_RED \u001B[31m; private static final String ANSI_RESET \u001B[0m; private static volatile boolean installed; /** true合并管道模式false双 fdJDK 式。 */ private static volatile boolean mergedStdoutMode; private static volatile PrintStream outStream; private static volatile PrintStream errStream; private static volatile PrintStream unifiedStream; private static volatile boolean ansiErrRed Boolean.parseBoolean(java.lang.System.getProperty(syncconsole.ansiErr, false)); private System2() { } /** * strong默认推荐/strong只使用标准输出 fd{link java.lang.System#out} 与 {link java.lang.System#err} 指向同一 {link PrintStream} * 控制台收到的字节顺序与 {link #println(Kind, String)} 调用顺序一致。{link Kind#ERR} 时默认带 {code [stderr] } 前缀 * 需要 ANSI 红字时可 {code -Dsyncconsole.ansiErrtrue}视控制台是否解析转义而定。 */ public static void installOrderedConsole() { installMergedStdoutInternal(); } /** * 与 {link #installOrderedConsole()} 相同实现合并管道、顺序优先。 */ public static void installMergedStdoutStrictOrder() { installMergedStdoutInternal(); } private static void installMergedStdoutInternal() { synchronized (CONSOLE_LOCK) { if (installed) { return; } try { OutputStream raw new FileOutputStream(FileDescriptor.out); OutputStream gated new GatedOutputStream(raw); PrintStream ps new PrintStream(gated, true, UTF-8); unifiedStream ps; java.lang.System.setOut(ps); java.lang.System.setErr(ps); mergedStdoutMode true; installed true; } catch (UnsupportedEncodingException e) { throw new IllegalStateException(UTF-8 must be supported, e); } } } /** * JDK 式双 fd{link java.lang.System#err} 走真实 stderr在 Eclipse 中一般为红色但strong不要期望/strong与 {link Kind#OUT} 交替时 * 显示顺序与源码一致IDE 分管道缓冲。 */ public static void installDualFileDescriptorConsole() { synchronized (CONSOLE_LOCK) { if (installed) { return; } try { FileOutputStream fosOut new FileOutputStream(FileDescriptor.out); FileOutputStream fosErr new FileOutputStream(FileDescriptor.err); outStream new PrintStream(fosOut, true, UTF-8); errStream new PrintStream(fosErr, true, UTF-8); java.lang.System.setOut(outStream); java.lang.System.setErr(errStream); mergedStdoutMode false; installed true; } catch (UnsupportedEncodingException e) { throw new IllegalStateException(UTF-8 must be supported, e); } } } /** * deprecated 语义同 {link #installDualFileDescriptorConsole()} */ Deprecated public static void installPrintStreamsLikeSystemClass() { installDualFileDescriptorConsole(); } public static void setAnsiErrRedEnabled(boolean enabled) { ansiErrRed enabled; } public static boolean isAnsiErrRedEnabled() { return ansiErrRed; } /** * 按通道输出一行换行。示例{code System2.println(System2.OUT, )}、{code System2.println(System2.ERR, msg)}。 * * param kind {link #OUT} 或 {link #ERR}不可为 {code null} * param message 文本{code null} 时与 {link PrintStream#println(String)} 一致 */ public static void println(Kind kind, String message) { if (kind null) { throw new IllegalArgumentException(kind is null); } if (kind Kind.OUT) { printlnOut(message); } else { printlnErr(message); } } /** * param kind {link #OUT} 或 {link #ERR} * param obj 将 {link String#valueOf(Object)} 再写出 */ public static void println(Kind kind, Object obj) { println(kind, String.valueOf(obj)); } /** * param kind {link #OUT} 或 {link #ERR} * param message 不换行{code null} 当作 */ public static void print(Kind kind, String message) { if (kind null) { throw new IllegalArgumentException(kind is null); } if (kind Kind.OUT) { printOut(message); } else { printErr(message); } } private static void printlnOut(String message) { ensureInstalled(); synchronized (CONSOLE_LOCK) { if (mergedStdoutMode) { unifiedStream.println(message); } else { outStream.println(message); outStream.flush(); } } } private static void printlnErr(String message) { ensureInstalled(); synchronized (CONSOLE_LOCK) { if (mergedStdoutMode) { if (ansiErrRed) { unifiedStream.print(ANSI_RED); unifiedStream.println(message); unifiedStream.print(ANSI_RESET); } else { unifiedStream.print(STDERR_PREFIX); unifiedStream.println(message); } } else { errStream.println(message); errStream.flush(); } } } private static void printOut(String message) { ensureInstalled(); synchronized (CONSOLE_LOCK) { if (mergedStdoutMode) { unifiedStream.print(message null ? : message); } else { outStream.print(message null ? : message); outStream.flush(); } } } private static void printErr(String message) { ensureInstalled(); synchronized (CONSOLE_LOCK) { if (mergedStdoutMode) { if (ansiErrRed) { unifiedStream.print(ANSI_RED); unifiedStream.print(message null ? : message); unifiedStream.print(ANSI_RESET); } else { unifiedStream.print(STDERR_PREFIX); unifiedStream.print(message null ? : message); } } else { errStream.print(message null ? : message); errStream.flush(); } } } public static void flush() { synchronized (CONSOLE_LOCK) { if (!installed) { return; } if (mergedStdoutMode) { if (unifiedStream ! null) { unifiedStream.flush(); } } else { if (outStream ! null) { outStream.flush(); } if (errStream ! null) { errStream.flush(); } } } } private static void ensureInstalled() { if (!installed) { throw new IllegalStateException(Call System2.installOrderedConsole() (or installMergedStdoutStrictOrder()) first); } } private static final class GatedOutputStream extends OutputStream { private final OutputStream delegate; GatedOutputStream(OutputStream delegate) { this.delegate delegate; } Override public void write(int b) throws IOException { synchronized (CONSOLE_LOCK) { delegate.write(b); } } Override public void write(byte[] b, int off, int len) throws IOException { synchronized (CONSOLE_LOCK) { delegate.write(b, off, len); } } Override public void flush() throws IOException { synchronized (CONSOLE_LOCK) { delegate.flush(); } } } }

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价