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.
To add files or folders to a zipped folder you created earlier, drag them to the zipped folder.
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.
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()
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With