40
40
*/
41
41
public
42
42
class DeflaterOutputStream extends FilterOutputStream {
43
+
44
+ /*
45
+ * The default size of the output buffer
46
+ */
47
+ static final int DEFAULT_BUF_SIZE = 512 ;
48
+
49
+ /*
50
+ * When calling Deflater.deflate() with Deflater.SYNC_FLUSH or Deflater.FULL_FLUSH,
51
+ * the callers are expected to ensure that the size of the buffer is greater than 6.
52
+ * This expectation comes from the underlying zlib library which in its zlib.h
53
+ * states:
54
+ * "If deflate returns with avail_out == 0, this function must be called again
55
+ * with the same value of the flush parameter and more output space (updated
56
+ * avail_out), until the flush is complete (deflate returns with non-zero
57
+ * avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
58
+ * avail_out is greater than six when the flush marker begins, in order to avoid
59
+ * repeated flush markers upon calling deflate() again when avail_out == 0."
60
+ */
61
+ private static final int SYNC_FLUSH_MIN_BUF_SIZE = 7 ;
62
+
43
63
/**
44
64
* Compressor for this stream.
45
65
*/
@@ -124,7 +144,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
124
144
public DeflaterOutputStream (OutputStream out ,
125
145
Deflater def ,
126
146
boolean syncFlush ) {
127
- this (out , def , 512 , syncFlush );
147
+ this (out , def , DEFAULT_BUF_SIZE , syncFlush );
128
148
}
129
149
130
150
@@ -139,7 +159,7 @@ public DeflaterOutputStream(OutputStream out,
139
159
* @param def the compressor ("deflater")
140
160
*/
141
161
public DeflaterOutputStream (OutputStream out , Deflater def ) {
142
- this (out , def , 512 , false );
162
+ this (out , def , DEFAULT_BUF_SIZE , false );
143
163
}
144
164
145
165
boolean usesDefaultDeflater = false ;
@@ -159,7 +179,7 @@ public DeflaterOutputStream(OutputStream out, Deflater def) {
159
179
* @since 1.7
160
180
*/
161
181
public DeflaterOutputStream (OutputStream out , boolean syncFlush ) {
162
- this (out , new Deflater (), 512 , syncFlush );
182
+ this (out , new Deflater (), DEFAULT_BUF_SIZE , syncFlush );
163
183
usesDefaultDeflater = true ;
164
184
}
165
185
@@ -182,6 +202,7 @@ public DeflaterOutputStream(OutputStream out) {
182
202
* @param b the byte to be written
183
203
* @exception IOException if an I/O error has occurred
184
204
*/
205
+ @ Override
185
206
public void write (int b ) throws IOException {
186
207
byte [] buf = new byte [1 ];
187
208
buf [0 ] = (byte )(b & 0xff );
@@ -196,6 +217,7 @@ public void write(int b) throws IOException {
196
217
* @param len the length of the data
197
218
* @exception IOException if an I/O error has occurred
198
219
*/
220
+ @ Override
199
221
public void write (byte [] b , int off , int len ) throws IOException {
200
222
if (def .finished ()) {
201
223
throw new IOException ("write beyond end of stream" );
@@ -239,6 +261,7 @@ public void finish() throws IOException {
239
261
* underlying stream.
240
262
* @exception IOException if an I/O error has occurred
241
263
*/
264
+ @ Override
242
265
public void close () throws IOException {
243
266
if (!closed ) {
244
267
try {
@@ -278,13 +301,20 @@ protected void deflate() throws IOException {
278
301
*
279
302
* @since 1.7
280
303
*/
304
+ @ Override
281
305
public void flush () throws IOException {
282
306
if (syncFlush && !def .finished ()) {
283
307
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 )
288
318
break ;
289
319
}
290
320
}
0 commit comments