Index: src/images.py =================================================================== --- src/images.py (Revision 51251) +++ src/images.py (Arbeitskopie) @@ -98,6 +98,7 @@ UCC_IMAGE_INDEX_FILE = 'image-index.txt' UCC_IMAGE_INDEX_URL = '%s/%s' % (UCC_BASE_URL, UCC_IMAGE_INDEX_FILE) DEFAULT_CHUNK_SIZE = 2**13 +BLOCK_SIZE = 4096 # block size is dependent on file system block size for sparse file def _dummy_progress(*args): @@ -165,10 +166,23 @@ break uncompressed_data = decompressor.decompress(compressed_data) - fout.write(uncompressed_data) + + # don't write blocks that consist only of 0-bytes to keep sparse file format + for i in xrange(0, len(uncompressed_data), BLOCK_SIZE): + if len(uncompressed_data[i:i+BLOCK_SIZE]) == BLOCK_SIZE: + if uncompressed_data[i:i+BLOCK_SIZE].count('\x00') == BLOCK_SIZE: + fout.seek(BLOCK_SIZE, os.SEEK_CUR) + else: + fout.write(uncompressed_data[i:i+BLOCK_SIZE]) + # decompressed data can not be always a multiple of BLOCK_SIZE + # so write rest data to avoid data loss + else: + if uncompressed_data[i:].count('\x00') == len(uncompressed_data[i:]): + fout.seek(len(uncompressed_data[i:]), os.SEEK_CUR) + else: + fout.write(uncompressed_data[i:]) + progress(fin.tell(), total_size) - del compressed_data - del uncompressed_data # check free size on disk every N rounds if counter % 50 == 0: