package com.prezi.io; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; public class BufferedStdOutputStreams { private List<Entry> entries = new ArrayList<Entry>(); private enum Type { STDOUT, STDERR } private void write(Type type, byte[] bytes) throws IOException { if (!entries.isEmpty() && entries.get(entries.size()-1).type.equals(type)) { Entry last = entries.get(entries.size()-1); last.bos.write(bytes); } else { entries.add(new Entry(type, bytes)); } } public OutputStream getStdOutOutputStream() { return new RedirectedOS(Type.STDOUT); } public OutputStream getStdErrOutputStream() { return new RedirectedOS(Type.STDERR); } public void printOutput() { for (Entry e : entries) { if (e.type.equals(Type.STDOUT)) { System.out.print(new String(e.bos.toByteArray())); } else if (e.type.equals(Type.STDERR)) { System.err.print(new String(e.bos.toByteArray())); } else { throw new RuntimeException("Unknown type: " + e.type); } } } public String getErrorOut() { StringBuilder sb = new StringBuilder(); for (Entry e : entries) { if (e.type.equals(Type.STDERR)) { sb.append(new String(e.bos.toByteArray())); } } return sb.toString(); } private class Entry { private Type type; private ByteArrayOutputStream bos = new ByteArrayOutputStream(); public Entry(Type type, byte[] bytes) throws IOException { this.type = type; this.bos.write(bytes); } } private class RedirectedOS extends OutputStream { private Type type; public RedirectedOS(Type type) { this.type = type; } @Override public void write(int b) throws IOException { write(new byte[]{(byte)b}); } public void write(byte b[]) throws IOException { BufferedStdOutputStreams.this.write(type, b); } } }