Search code examples
python-3.xzipbytesio

Why I Cannot unzip a zipped file by python zipfile?


no.1:

def run():
    with open('module1/2020-06-csv.zip', 'rb') as f:
        io = BytesIO(f.read())
    zip_file = zipfile.ZipFile(io)
    zip_buffer = 'module1/myzip.zip'
    my_zip = zipfile.ZipFile(
        zip_buffer,
        mode='w',
        compression=zipfile.ZIP_DEFLATED
    )
    for file in zip_file.filelist:
        if file.filename.endswith('/'):
            continue
        filename = file.filename.split('/')[-1]
        with zip_file.open(file.filename) as f:
            my_zip.writestr(zinfo_or_arcname=filename, data=f.read())

With the no.1 method, I can unzip the 'myzip.zip' file succeed. But, I used BytesIO(no.2) instead of local file, and I cannot unzip the 'myzip.zip' file, what's wrong?

no.2

def run():
    with open('module1/2020-06-csv.zip', 'rb') as f:
        io = BytesIO(f.read())
    zip_file = zipfile.ZipFile(io)
    # zip_buffer = 'module1/myzip.zip'
    zip_buffer = BytesIO()
    my_zip = zipfile.ZipFile(
        zip_buffer,
        mode='w',
        compression=zipfile.ZIP_DEFLATED
    )
    for file in zip_file.filelist:
        if file.filename.endswith('/'):
            continue
        filename = file.filename.split('/')[-1]
        with zip_file.open(file.filename) as f:
            my_zip.writestr(zinfo_or_arcname=filename, data=f.read())

    zip_buffer.seek(0)

    with open('module1/myzip.zip', 'wb') as f:
        f.write(zip_buffer.read())

    zip_file.close()
    my_zip.close()

Solution

  • You have to call my_zip.close() for the output zip file to be usable. You didn't show that in No. 1, but I think it must have been there if it worked.

    In No. 2, you write out the contents of zip_buffer to a file before calling my_zip.close(), so the file is unusable. You call my_zip.close() later, but since you have already written out the contents of zip_buffer, it's too late to do any good.

    So to fix it, you just have to move the call to my_zip.close() before the writing of the contents of zip_buffer to a file.