4141 */
4242public
4343class DeflaterOutputStream extends FilterOutputStream {
44+
45+ /*
46+ * The default size of the output buffer
47+ */
48+ static final int DEFAULT_BUF_SIZE = 512 ;
49+
50+ /*
51+ * When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
52+ * the callers are expected to ensure that the size of the buffer is greater than 6.
53+ * This expectation comes from the underlying zlib library which in its zlib.h
54+ * states:
55+ * "If deflate returns with avail_out == 0, this function must be called again
56+ * with the same value of the flush parameter and more output space (updated
57+ * avail_out), until the flush is complete (deflate returns with non-zero
58+ * avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
59+ * avail_out is greater than six when the flush marker begins, in order to avoid
60+ * repeated flush markers upon calling deflate() again when avail_out == 0."
61+ */
62+ private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7 ;
63+
4464 /**
4565 * Compressor for this stream.
4666 */
@@ -124,7 +144,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
124144 public DeflaterOutputStream (OutputStream out ,
125145 Deflater def ,
126146 boolean syncFlush ) {
127- this (out , def , 512 , syncFlush );
147+ this (out , def , DEFAULT_BUF_SIZE , syncFlush );
128148 }
129149
130150
@@ -139,7 +159,7 @@ public DeflaterOutputStream(OutputStream out,
139159 * @param def the compressor ("deflater")
140160 */
141161 public DeflaterOutputStream (OutputStream out , Deflater def ) {
142- this (out , def , 512 , false );
162+ this (out , def , DEFAULT_BUF_SIZE , false );
143163 }
144164
145165 boolean usesDefaultDeflater = false ;
@@ -159,7 +179,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
159179 * @since 1.7
160180 */
161181 public DeflaterOutputStream (OutputStream out , boolean syncFlush ) {
162- this (out , new Deflater (), 512 , syncFlush );
182+ this (out , new Deflater (), DEFAULT_BUF_SIZE , syncFlush );
163183 usesDefaultDeflater = true ;
164184 }
165185
@@ -182,6 +202,7 @@ public DeflaterOutputStream(OutputStream out) {
182202 * @param b the byte to be written
183203 * @exception IOException if an I/O error has occurred
184204 */
205+ @ Override
185206 public void write (int b ) throws IOException {
186207 byte [] buf = new byte [1 ];
187208 buf [0 ] = (byte )(b & 0xff );
@@ -196,6 +217,7 @@ public void write(int b) throws IOException {
196217 * @param len the length of the data
197218 * @exception IOException if an I/O error has occurred
198219 */
220+ @ Override
199221 public void write (byte [] b , int off , int len ) throws IOException {
200222 if (def .finished ()) {
201223 throw new IOException ("write beyond end of stream" );
@@ -239,6 +261,7 @@ public void finish() throws IOException {
239261 * underlying stream.
240262 * @exception IOException if an I/O error has occurred
241263 */
264+ @ Override
242265 public void close () throws IOException {
243266 if (!closed ) {
244267 try {
@@ -278,13 +301,20 @@ protected void deflate() throws IOException {
278301 *
279302 * @since 1.7
280303 */
304+ @ Override
281305 public void flush () throws IOException {
282306 if (syncFlush && !def .finished ()) {
283307 int len = 0 ;
284- while ((len = def .deflate (buf , 0 , buf .length , Deflater .SYNC_FLUSH )) > 0 )
285- {
286- out .write (buf , 0 , len );
287- if (len < buf .length )
308+ // For SYNC_FLUSH, the Deflater.deflate() expects the callers
309+ // to use a buffer whose length is greater than 6 to avoid
310+ // flush marker (5 bytes) being repeatedly output to the output buffer
311+ // every time it is invoked.
312+ final byte [] flushBuf = buf .length < SYNC_FLUSH_MIN_BUF_SIZE
313+ ? new byte [DEFAULT_BUF_SIZE ]
314+ : buf ;
315+ while ((len = def .deflate (flushBuf , 0 , flushBuf .length , Deflater .SYNC_FLUSH )) > 0 ) {
316+ out .write (flushBuf , 0 , len );
317+ if (len < flushBuf .length )
288318 break ;
289319 }
290320 }
0 commit comments