简体   繁体   中英

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM