Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Open zip file from binary instead of filename

Tags:

python

zip

Is there any way to initialize a ZipFile object by passing in the literal bytes of the zip file, instead of having it read a filename? I'm building a restful app that doesn't need to ever touch the disk; it just opens the file, does some work on it, re-zips it and sends it on.

like image 486
limp_chimp Avatar asked Dec 26 '22 20:12

limp_chimp


1 Answers

In comments on the other answers, you say you want to do this:

open a binary string as if it were a zip file. Open it, read/write to files inside of it, and then close it

You just do the same thing as in the other answers, except you create a StringIO.StringIO (or cStringIO.StringIO or io.BytesIO) that's pre-filled with the binary string, and extract the string in the end. StringIO and friends take an optional initial string for their constructor, and have a getvalue method to extract the string when you're done. The documentation is very simple, and worth reading.

So, sticking as close to alecxe's answer as possible:

from zipfile import ZipFile
try:
    import cStringIO as StringIO
except ImportError:
    import StringIO

in_memory = StringIO.StringIO(original_zip_data)
zf = ZipFile(in_memory, "a")  

zf.writestr("file.txt", "some text contents")

zf.close()

new_zip_data = in_memory.getvalue()

However, note that ZipFile can't really write to a zip archive in-place, except for the special case of appending new files to it. This is just as true for in-memory zip archives as on-disk. You can often get away with overwriting a file in the archive by appending a new file with the same path, but that's usually a bad idea (especially if you're creating these things to be sent over the internet).

So, what you probably want to do is exactly the same as when you want to modify a file: create a separate output file, copy the things you need from the input file and write the new things as you go along. It's just that in this case, the input and output files are both ZipFile objects wrapping StringIO objects.

like image 148
abarnert Avatar answered Dec 28 '22 10:12

abarnert