@@ -60,7 +60,7 @@ def open(filename, mode="rb", compresslevel=gzip_ng._COMPRESS_LEVEL_TRADEOFF,
60
60
gzip_file = io .BufferedReader (
61
61
_ThreadedGzipReader (filename , block_size = block_size ))
62
62
else :
63
- gzip_file = io . BufferedWriter (
63
+ gzip_file = FlushableBufferedWriter (
64
64
_ThreadedGzipWriter (
65
65
filename ,
66
66
mode .replace ("t" , "b" ),
@@ -167,6 +167,12 @@ def closed(self) -> bool:
167
167
return self ._closed
168
168
169
169
170
+ class FlushableBufferedWriter (io .BufferedWriter ):
171
+ def flush (self ):
172
+ super ().flush ()
173
+ self .raw .flush ()
174
+
175
+
170
176
class _ThreadedGzipWriter (io .RawIOBase ):
171
177
"""
172
178
Write a gzip file using multiple threads.
@@ -315,30 +321,35 @@ def write(self, b) -> int:
315
321
self .input_queues [worker_index ].put ((data , zdict ))
316
322
return len (data )
317
323
318
- def flush (self ):
324
+ def _end_gzip_stream (self ):
319
325
self ._check_closed ()
320
326
# Wait for all data to be compressed
321
327
for in_q in self .input_queues :
322
328
in_q .join ()
323
329
# Wait for all data to be written
324
330
for out_q in self .output_queues :
325
331
out_q .join ()
332
+ # Write an empty deflate block with a lost block marker.
333
+ self .raw .write (zlib_ng .compress (b"" , wbits = - 15 ))
334
+ trailer = struct .pack ("<II" , self ._crc , self ._size & 0xFFFFFFFF )
335
+ self .raw .write (trailer )
336
+ self ._crc = 0
337
+ self ._size = 0
326
338
self .raw .flush ()
327
339
340
+ def flush (self ):
341
+ self ._end_gzip_stream ()
342
+ self ._write_gzip_header ()
343
+
328
344
def close (self ) -> None :
329
345
if self ._closed :
330
346
return
331
- self .flush ()
347
+ self ._end_gzip_stream ()
332
348
self .stop ()
333
349
if self .exception :
334
350
self .raw .close ()
335
351
self ._closed = True
336
352
raise self .exception
337
- # Write an empty deflate block with a lost block marker.
338
- self .raw .write (zlib_ng .compress (b"" , wbits = - 15 ))
339
- trailer = struct .pack ("<II" , self ._crc , self ._size & 0xFFFFFFFF )
340
- self .raw .write (trailer )
341
- self .raw .flush ()
342
353
if self .closefd :
343
354
self .raw .close ()
344
355
self ._closed = True
@@ -371,41 +382,31 @@ def _compress(self, index: int):
371
382
def _write (self ):
372
383
index = 0
373
384
output_queues = self .output_queues
374
- fp = self .raw
375
- total_crc = 0
376
- size = 0
377
385
while self ._calling_thread .is_alive ():
378
386
out_index = index % self .threads
379
387
output_queue = output_queues [out_index ]
380
388
try :
381
389
compressed , crc , data_length = output_queue .get (timeout = 0.05 )
382
390
except queue .Empty :
383
391
if not self .running :
384
- self ._crc = total_crc
385
- self ._size = size
386
392
return
387
393
continue
388
- total_crc = zlib_ng .crc32_combine (total_crc , crc , data_length )
389
- size += data_length
390
- fp .write (compressed )
394
+ self . _crc = zlib_ng .crc32_combine (self . _crc , crc , data_length )
395
+ self . _size += data_length
396
+ self . raw .write (compressed )
391
397
output_queue .task_done ()
392
398
index += 1
393
399
394
400
def _compress_and_write (self ):
395
401
if not self .threads == 1 :
396
402
raise SystemError ("Compress_and_write is for one thread only" )
397
- fp = self .raw
398
- total_crc = 0
399
- size = 0
400
403
in_queue = self .input_queues [0 ]
401
404
compressor = self .compressors [0 ]
402
405
while self ._calling_thread .is_alive ():
403
406
try :
404
407
data , zdict = in_queue .get (timeout = 0.05 )
405
408
except queue .Empty :
406
409
if not self .running :
407
- self ._crc = total_crc
408
- self ._size = size
409
410
return
410
411
continue
411
412
try :
@@ -415,9 +416,9 @@ def _compress_and_write(self):
415
416
self ._set_error_and_empty_queue (e , in_queue )
416
417
return
417
418
data_length = len (data )
418
- total_crc = zlib_ng .crc32_combine (total_crc , crc , data_length )
419
- size += data_length
420
- fp .write (compressed )
419
+ self . _crc = zlib_ng .crc32_combine (self . _crc , crc , data_length )
420
+ self . _size += data_length
421
+ self . raw .write (compressed )
421
422
in_queue .task_done ()
422
423
423
424
def _set_error_and_empty_queue (self , error , q ):
0 commit comments