import java.io.*; import java.util.zip.*; public class CompressedOutputStream extends FilterOutputStream { protected byte buf[]; // The internal buffer where uncompressed data is stored protected int count; // The number of valid bytes in the buffer protected int size; // Total size of the buffer. public CompressedOutputStream(OutputStream out) { this(out, 512); } public CompressedOutputStream(OutputStream out, int size) { super(out); if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } this.size = size; buf = new byte[size]; } private void flushBuffer() throws IOException { if (count > 0) { writeBuffer(buf, 0, count); count = 0; } } private void writeBuffer(byte buf[], int offset, int len) throws IOException { DeflaterOutputStream dos = new DeflaterOutputStream(out); DataOutputStream dataOut = new DataOutputStream(dos); dataOut.writeInt(len); // write number of data bytes System.err.println("writing "+len); dataOut.write(buf,0,len); // write out compressed data dataOut.flush(); dos.finish(); out.flush(); buf = new byte[size]; } public synchronized void write(int b) throws IOException { if (count >= buf.length) { flushBuffer(); } buf[count++] = (byte)b; } public synchronized void write(byte b[], int off, int len) throws IOException { if (len >= buf.length) { /* If the request length exceeds the size of the output buffer, flush the output buffer and then write the data directly. In this way buffered streams will cascade harmlessly. */ flushBuffer(); writeBuffer(b, off, len); return; } if (len > buf.length - count) { flushBuffer(); } System.arraycopy(b, off, buf, count, len); count += len; } public synchronized void flush() throws IOException { flushBuffer(); out.flush(); } }