I'm trying to create, using python, a zip file to be later used in a http response. To achieve this I'm using a io.BytesIO() as file object.
The resulting zip file is somehow corrupted: some software like unzip don't like it while others like zcat do read contents.
Here a minimal example, I will save to file the resulting zip instead of serving in a resoponse. The error is the same I get in my real application:
$ cat << EOF > script.py
> import io
import zipfile
with (io.BytesIO() as fo,
zipfile.ZipFile(fo, 'w') as zip,
open('outfile.zip', 'wb') as outfile):
zip.writestr('file.txt', b'Lorem ipsum')
fo.seek(0)
outfile.write(fo.read())
> EOF
$ python3 script.py
$ ll outfile.zip
-rw-rw-r-- 1 neurino neurino 49 mar 11 14:38 outfile.zip
$ unzip outfile.zip
Archive: outfile.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of outfile.zip or
outfile.zip.zip, and cannot find outfile.zip.ZIP, period.
$ zcat outfile.zip
Lorem ipsum
Using a file in place of a file object the resulting zip file works — and also is bigger
$ cat << EOF > script2.py
> import io
> import zipfile
> with zipfile.ZipFile('outfile.zip', 'w') as zip:
> zip.writestr('file.txt', b'Lorem ipsum')
$ python3 script2.py
$ ll outfile.zip
-rw-rw-r-- 1 user user 125 mar 11 14:41 outfile.zip
$ unzip outfile.zip
Archive: outfile.zip
extracting: file.txt
I got the issue myself: I'm reading file object within the
with zipfile.ZipFileblock, before its__exit__block gets executed.This script works as intended: