Java 允许您提供自己PrintStream
的覆盖stdout
和stderr
一个InputStream
for stdin
。
就个人而言,我不喜欢简单地丢弃原始流,因为我倾向于只想重定向或解析它,而不是停止它(尽管你也可以这样做)。
这是这个想法的一个简单例子......
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
public class RedirectStdOut {
public static void main(String[] args) {
Consumer stdConsumer = new Consumer() {
@Override
public void processLine(StreamCapturer capturer, String text) {
}
@Override
public void processCharacter(StreamCapturer capturer, char character) {
capturer.getParent().print(character);
}
};
StreamCapturer stdout = new StreamCapturer(stdConsumer, System.out);
StreamCapturer stderr = new StreamCapturer(stdConsumer, System.err);
System.setOut(new PrintStream(stdout));
System.setErr(new PrintStream(stderr));
System.out.println("This is a test");
System.err.println("This is an err");
}
public static interface Consumer {
public void processLine(StreamCapturer capturer, String text);
public void processCharacter(StreamCapturer capturer, char character);
}
public static class StreamCapturer extends OutputStream {
private StringBuilder buffer;
private Consumer consumer;
private PrintStream parent;
private boolean echo = false;
public StreamCapturer(Consumer consumer, PrintStream parent) {
buffer = new StringBuilder(128);
this.parent = parent;
this.consumer = consumer;
}
public PrintStream getParent() {
return parent;
}
public boolean shouldEcho() {
return echo;
}
public void setEcho(boolean echo) {
this.echo = echo;
}
@Override
public void write(int b) throws IOException {
char c = (char) b;
String value = Character.toString(c);
buffer.append(value);
if (value.equals("\n")) {
consumer.processLine(this, value);
buffer.delete(0, buffer.length());
}
consumer.processCharacter(this, c);
if (shouldEcho()) {
parent.print(c);
}
}
}
}
现在,StreamCapturer
如果您愿意,可以回显输出,我已将其关闭以演示Consumer
. 我通常会使用Consumer
来处理流中的内容,根据您的需要,您可以等待完整的行或处理单个字符...