如果您正在使用Eclipse控制台,似乎有两种不同的现象在起作用:
之一,如@Gemtast,是JVM处理流的方式,另一种是Eclipse读取这些流的方式,如@DraganBozanovic..因为我在使用Eclipse,优雅的flush()-张贴的解决办法@BillK,仅解决JVM问题是不够的。
最后我给自己写了一个叫做EclipseTools具有以下内容(以及所需的包声明和导入)。这有点麻烦,但解决了这两个问题:public class EclipseTools {
private static List streams = null;
private static OutputStream lastStream = null;
private static class FixedStream extends OutputStream {
private final OutputStream target;
public FixedStream(OutputStream originalStream) {
target = originalStream;
streams.add(this);
}
@Override
public void write(int b) throws IOException {
if (lastStream!=this) swap();
target.write(b);
}
@Override
public void write(byte[] b) throws IOException {
if (lastStream!=this) swap();
target.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (lastStream!=this) swap();
target.write(b, off, len);
}
private void swap() throws IOException {
if (lastStream!=null) {
lastStream.flush();
try { Thread.sleep(200); } catch (InterruptedException e) {}
}
lastStream = this;
}
@Override public void close() throws IOException { target.close(); }
@Override public void flush() throws IOException { target.flush(); }
}
/**
* Inserts a 200ms delay into the System.err or System.out OutputStreams
* every time the output switches from one to the other. This prevents
* the Eclipse console from showing the output of the two streams out of
* order. This function only needs to be called once.
*/
public static void fixConsole() {
if (streams!=null) return;
streams = new ArrayList();
System.setErr(new PrintStream(new FixedStream(System.err)));
System.setOut(new PrintStream(new FixedStream(System.out)));
}}
要使用,只需打电话EclipseTools.fixConsole()一次在代码的开头。
基本上,这将替换两个流。System.err和System.out使用一组自定义的流,这些流简单地将其数据转发到原始流,但是要跟踪哪个流是写入到最后的。如果写入的流更改,例如System.err.something(...)后面是System.out.something(...),它刷新最后一个流的输出,等待200 ms,以便Eclipse控制台有时间完成打印。
注意:200 ms只是一个粗略的初始值。如果此代码减少了,但没有为您消除问题,则增加Thread.sleep从200到更高直到它起作用。或者,如果此延迟有效,但会影响代码的性能(如果您经常交替使用流),您可以尝试逐步减少它,直到开始出现错误。