Python zipfile module doesn't compress files
Asked Answered
G

2

8

I have a problem with compression in Python. I know I should call the ZIP_DEFLATED method when writing to make the zip file compressed, but it does not work for me. I have 3 PDF documents in the C:zip directory. When I run the following code it works just fine:

import os,sys
list = os.listdir('C:\zip')
file = ZipFile('test.zip','w')
for item in list:
    file.write(item)
file.close()

It makes the test.zip file without the compression. When I change the fourth row to this:

file = ZipFile('test.zip','w', compression = ZIP_DEFLATED)

It also makes the test.zip file without the compression. I also tried to change the write method to give it the compress_ type argument:

file.write(item, compress_type = ZIP_DEFLATED)

But that doesn't work either. I use Python version 2.7.4 with Win7. I tired the code with another computer (same circumstances, Win7 and Python 2.7.4), and it made the test.zip file compressed just like it should. I know the zlib module should be available, when I run this:

import zlib

It doesn't return an error, also if there would be something wrong with the zlib module the code at the top should had return an error too, so I suspect that zlib isn't the problem.

Gastrocnemius answered 9/8, 2013 at 16:54 Comment(2)
How are you checking whether the end zip file has been created with or without compression?Dollop
The documentation for the Zipfile constructor says "If ZIP_DEFLATED is specified but the zlib module is not available, RuntimeError is also raised." So if you don't get an error it should work. Note, it's not necessary to specify a compress_type keyword argument on a write() call unless you want to override the value given for the compression parameter to the constructor.Packton
S
17

By default the ZIP module only store data, to compress it you can do this:

import zipfile
try:
    import zlib
    mode= zipfile.ZIP_DEFLATED
except:
    mode= zipfile.ZIP_STORED

zip= zipfile.ZipFile('zipfilename', 'w', mode)
zip.write(item)
zip.close()
Sidereal answered 9/8, 2013 at 20:40 Comment(5)
Unfortunately this isn't working either. The mode variable returns an '8', so it sets the mode to ZIP_DEFLATED succesfully, but the zipfile is still too big.Gastrocnemius
"Still too big", but poorly compressed or uncompressed at all?Sidereal
Sorry, it seems to work now, looks like I made a mistake in the code eariler when trying it with other files. After that I was only working with the 3 PDF documents and the size of the compressed file was near as big as the size of the 3 PDF documents, and I thought the compression is still not working. Thanks for the help!Gastrocnemius
Ok, you are welcome! If you think this is a valid answer to your question then will be nice if you mark it as accepted!Sidereal
How is ZIP_STORED the default?!?! D: Whow! Thanks for clearing this up! 7zip makes much smaller zips tho 🤔Deadandalive
R
1

In case you get here as I did, I'll add something. If you use ZipInfo objects, they always override the compression method specified while creating the ZipFile, which is then useless.

So either you set their compression method (no parameter on the constructor, you must set the attribute) or specify the compression method when calling write (or writestr).

import zlib
from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED

def write_things():
    zip_buffer = io.BytesIO()
    with ZipFile(file = zip_buffer, mode = "w", compression = ZIP_DEFLATED) as zipper:
        # Get some data to write
        fname, content, zip_ts = get_file_data()
        file_object = ZipInfo(fname, zip_ts)
        zipper.writestr(file_object, content)   # Surprise, no compression

#       This is required to get compression
#       zipper.writestr(file_object, content, compress_type = ZIP_DEFLATED)
Rager answered 17/10, 2022 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.