5757 * @since 1.1
5858 */
5959public class DeflaterOutputStream extends FilterOutputStream {
60+
61+ /*
62+ * The default size of the output buffer
63+ */
64+ static final int DEFAULT_BUF_SIZE = 512 ;
65+
66+ /*
67+ * When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
68+ * the callers are expected to ensure that the size of the buffer is greater than 6.
69+ * This expectation comes from the underlying zlib library which in its zlib.h
70+ * states:
71+ * "If deflate returns with avail_out == 0, this function must be called again
72+ * with the same value of the flush parameter and more output space (updated
73+ * avail_out), until the flush is complete (deflate returns with non-zero
74+ * avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
75+ * avail_out is greater than six when the flush marker begins, in order to avoid
76+ * repeated flush markers upon calling deflate() again when avail_out == 0."
77+ */
78+ private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7 ;
79+
6080 /**
6181 * Compressor for this stream.
6282 */
@@ -152,7 +172,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
152172 public DeflaterOutputStream (OutputStream out ,
153173 Deflater def ,
154174 boolean syncFlush ) {
155- this (out , def , 512 , syncFlush );
175+ this (out , def , DEFAULT_BUF_SIZE , syncFlush );
156176 }
157177
158178
@@ -171,7 +191,7 @@ public DeflaterOutputStream(OutputStream out,
171191 * @param def the compressor ("deflater")
172192 */
173193 public DeflaterOutputStream (OutputStream out , Deflater def ) {
174- this (out , def , 512 , false );
194+ this (out , def , DEFAULT_BUF_SIZE , false );
175195 }
176196
177197 boolean usesDefaultDeflater = false ;
@@ -195,7 +215,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
195215 * @since 1.7
196216 */
197217 public DeflaterOutputStream (OutputStream out , boolean syncFlush ) {
198- this (out , out != null ? new Deflater () : null , 512 , syncFlush );
218+ this (out , out != null ? new Deflater () : null , DEFAULT_BUF_SIZE , syncFlush );
199219 usesDefaultDeflater = true ;
200220 }
201221
@@ -342,10 +362,16 @@ protected void deflate() throws IOException {
342362 public void flush () throws IOException {
343363 if (syncFlush && !def .finished ()) {
344364 int len = 0 ;
345- while ((len = def .deflate (buf , 0 , buf .length , Deflater .SYNC_FLUSH )) > 0 )
346- {
347- out .write (buf , 0 , len );
348- if (len < buf .length )
365+ // For SYNC_FLUSH, the Deflater.deflate() expects the callers
366+ // to use a buffer whose length is greater than 6 to avoid
367+ // flush marker (5 bytes) being repeatedly output to the output buffer
368+ // every time it is invoked.
369+ final byte [] flushBuf = buf .length < SYNC_FLUSH_MIN_BUF_SIZE
370+ ? new byte [DEFAULT_BUF_SIZE ]
371+ : buf ;
372+ while ((len = def .deflate (flushBuf , 0 , flushBuf .length , Deflater .SYNC_FLUSH )) > 0 ) {
373+ out .write (flushBuf , 0 , len );
374+ if (len < flushBuf .length )
349375 break ;
350376 }
351377 }
0 commit comments