Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a file-like object to a Zip file in Python

Tags:

python

django

zip

The Python ZipFile API seems to allow the passing of a file path to ZipFile.write or a byte string to ZipFile.writestr but nothing in between. I would like to be able to pass a file like object, in this case a django.core.files.storage.DefaultStorage but any file-like object in principle. At the moment I think I'm going to have to either save the file to disk, or read it into memory. Neither of these is perfect.

like image 687
Joe Avatar asked Nov 09 '11 16:11

Joe


People also ask

Can you add file to zip?

To add files or folders to a zipped folder you created earlier, drag them to the zipped folder.

How do you create a ZIP file in Python?

Create a zip archive from multiple files in Python Create a ZipFile object by passing the new file name and mode as 'w' (write mode). It will create a new zip file and open it within ZipFile object. Call write() function on ZipFile object to add the files in it. call close() on ZipFile object to Close the zip file.


2 Answers

You are correct, those are the only two choices. If your DefaultStorage object is large, you may want to go with saving it to disk first; otherwise, I would use:

zipped = ZipFile(...)
zipped.writestr('archive_name', default_storage_object.read())

If default_storage_object is a StringIO object, it can use default_storage_object.getvalue().

like image 81
Ethan Furman Avatar answered Oct 12 '22 11:10

Ethan Furman


While there's no option that takes a file-like object, there is an option to open a zip entry for writing (ZipFile.open). [doc]

import zipfile
import shutil
with zipfile.ZipFile('test.zip','w') as archive:
    with archive.open('test_entry.txt','w') as outfile:
        with open('test_file.txt','rb') as infile:
            shutil.copyfileobj(infile, outfile)

You can use your input stream as the source instead, and not have to copy the file to disk first. The downside is that if something goes wrong with your stream, the zip file will be unusable. In my application, we bypass files with errors, so we end up getting a local copy of the file anyway to ensure integrity and keep a usable zip file.

like image 22
Jason H Avatar answered Oct 12 '22 13:10

Jason H