protected byte[] buffer;
/** An End-Of-File (or buffer, here) marker. */
protected boolean eof;
+ /** The actual under-laying stream. */
+ protected OutputStream out;
+ /** The number of bytes written to the under-laying stream. */
+ protected long bytesWritten;
+ /**
+ * Can bypass the flush process for big writes (will directly write to the
+ * under-laying buffer if the array to write is > the internal buffer
+ * size).
+ * <p>
+ * By default, this is true.
+ */
+ protected boolean bypassFlush = true;
private boolean closed;
- private OutputStream out;
private int openCounter;
-
- private long bytesWritten;
+ private byte[] b1;
/**
* Create a new {@link BufferedInputStream} that wraps the given
this.out = out;
this.buffer = new byte[4096];
+ this.b1 = new byte[1];
this.start = 0;
this.stop = 0;
}
@Override
public void write(int b) throws IOException {
- checkClose();
-
- if (available() <= 0) {
- flush(false);
- }
-
- buffer[start++] = (byte) b;
+ b1[0] = (byte) b;
+ write(b1, 0, 1);
}
@Override
return;
}
- if (sourceLength >= buffer.length) {
+ if (bypassFlush && sourceLength >= buffer.length) {
/*
* If the request length exceeds the size of the output buffer,
* flush the output buffer and then write the data directly. In this
*/
flush(false);
out.write(source, sourceOffset, sourceLength);
+ bytesWritten += (sourceLength - sourceOffset);
return;
}
flush(false);
}
- int now = Math.min(sourceLength, available());
+ int now = Math.min(sourceLength - done, available());
System.arraycopy(source, sourceOffset + done, buffer, stop, now);
stop += now;
done += now;
}
/**
- * Flush the {@link BufferedOutputStream}, and optionally the under-laying
- * stream, too.
+ * Flush the {@link BufferedOutputStream}, write the current buffered data
+ * to (and optionally also flush) the under-laying stream.
+ * <p>
+ * If {@link BufferedOutputStream#bypassFlush} is false, all writes to the
+ * under-laying stream are done in this method.
+ * <p>
+ * This can be used if you want to write some data in the under-laying
+ * stream yourself (in that case, flush this {@link BufferedOutputStream}
+ * with or without flushing the under-laying stream, then you can write to
+ * the under-laying stream).
*
* @param includingSubStream
* also flush the under-laying stream
* @throws IOException
* in case of I/O error
*/
- private void flush(boolean includingSubStream) throws IOException {
- out.write(buffer, start, stop - start);
- bytesWritten += (stop - start);
+ public void flush(boolean includingSubStream) throws IOException {
+ if (stop > start) {
+ out.write(buffer, start, stop - start);
+ bytesWritten += (stop - start);
+ }
start = 0;
stop = 0;
+
if (includingSubStream) {
out.flush();
}
openCounter--;
} else {
closed = true;
- flush(true);
+ flush(includingSubStream);
if (includingSubStream && out != null) {
out.close();
}