Question

How do I write an in memory zipfile to a file?

# Create in memory zip and add files
zf = zipfile.ZipFile(StringIO.StringIO(), mode='w',compression=zipfile.ZIP_DEFLATED)
zf.writestr('file1.txt', "hi")
zf.writestr('file2.txt', "hi")

# Need to write it out
f = file("C:/path/my_zip.zip", "w")
f.write(zf)  # what to do here? Also tried f.write(zf.read())

f.close()
zf.close()
Was it helpful?

Solution

StringIO.getvalue return content of StringIO:

>>> import StringIO
>>> f = StringIO.StringIO()
>>> f.write('asdf')
>>> f.getvalue()
'asdf'

Alternatively, you can change position of the file using seek:

>>> f.read()
''
>>> f.seek(0)
>>> f.read()
'asdf'

Try following:

mf = StringIO.StringIO()
with zipfile.ZipFile(mf, mode='w', compression=zipfile.ZIP_DEFLATED) as zf:
    zf.writestr('file1.txt', "hi")
    zf.writestr('file2.txt', "hi")

with open("C:/path/my_zip.zip", "wb") as f: # use `wb` mode
    f.write(mf.getvalue())

OTHER TIPS

Modify falsetru's answer for python3

1) use io.StringIO instead of StringIO.StringIO

StringIO in python3

2) use b"abc" instead of "abc" , or

python 3.5: TypeError: a bytes-like object is required, not 'str' when writing to a file

3) encode to binary string str.encode(s, "utf-8")

Best way to convert string to bytes in Python 3?

import zipfile
import io
mf = io.BytesIO()

with zipfile.ZipFile(mf, mode="w",compression=zipfile.ZIP_DEFLATED) as zf:

    zf.writestr('file1.txt', b"hi")

    zf.writestr('file2.txt', str.encode("hi"))
    zf.writestr('file3.txt', str.encode("hi",'utf-8'))


with open("a.txt.zip", "wb") as f: # use `wb` mode
    f.write(mf.getvalue())

This should also work for gzip: How do I gzip compress a string in Python?

  with ZipFile(read_file, 'r') as zipread:
        with ZipFile(file_write_buffer, 'w', ZIP_DEFLATED) as zipwrite:
            for item in zipread.infolist():
                # Copy all ZipInfo attributes for each file since defaults are not preseved
                dest.CRC = item.CRC
                dest.date_time = item.date_time
                dest.create_system = item.create_system
                dest.compress_type = item.compress_type
                dest.external_attr = item.external_attr
                dest.compress_size = item.compress_size
                dest.file_size = item.file_size
                dest.header_offset = item.header_offset

In the case where the zip file reads corrupted and you notice missing symlinks or corrupted files with wrong timestamps, it could be the fact that the file properties are not getting copied over.

The above code snippet is how I solved the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top