简体   繁体   中英

Python zipfile.ZipFile zips a corrupt file

I have a Django view which users can call to zip files at my local server. It uses zipfile.ZipFile to compresses multiple files into a single zip as follows:

with ZipFile(my_dir + 'folder.zip', 'w') as zipObj:
                zipObj.write(my_dir + '1.json')
                zipObj.write(my_dir + '2.json')

Then I return this file to the user in response:

folder_file = open(full_path, "r", encoding='Cp437')
            response = HttpResponse(FileWrapper(folder_file), content_type='application/zip')

But the downloaded file is corrupt, I can't open it using ubuntu archive manager.

Then when i try to unzip the file using python with the same package in my django server, I still get the error:

with ZipFile(file_path, 'r') as zip_ref:
            zip_ref.extractall(my_dir)

The error I get is:

  File ".../views.py", line 38, in post
    with ZipFile(file_path, 'r') as zip_ref:
  File "/usr/lib/python3.8/zipfile.py", line 1269, in __init__
    self._RealGetContents()
  File "/usr/lib/python3.8/zipfile.py", line 1354, in _RealGetContents
    fp.seek(self.start_dir, 0)
OSError: [Errno 22] Invalid argument

Any idea what am I doing wrong here?

This should be a comment, but i think it's to long.

I think you should have a look at your paths, because wrong path can lead to unwanted behaviour. From the zipfile write :

Archive names should be relative to the archive root, that is, they should not start with a path separator.

and from zipfile extratc (all) :

If a member filename is an absolute path, a drive/UNC sharepoint and leading (back)slashes will be stripped, eg: ///foo/bar becomes foo/bar on Unix, and C:\foo\bar becomes foo\bar on Windows. And all ".." components in a member filename will be removed, eg: ../../foo../../ba..r becomes foo../ba..r. On Windows illegal characters (:, <, >, |, ", ?, and *) replaced by underscore (_).

So make shure you use a correct path. And make shure they do not have problematic characters (like wildcards or backslashes) like here

Maybe you should test with other (un-) zip tootls to see if it makes a difference, Sometimes they are more concrete ( Like here )

you can try something like this.

zipf = ZipFile("whatever.zip", "w")

for file in files_to_add:
    this_file = urlopen(file).read()
    this_filename = 'file name.json'
    zipf.writestr(this_filename, this_file)

zipf.close()

response = HttpResponse(io.open("whatever.zip", mode="rb").read(), content_type="application/zip")
response["Content-Disposition"] = "attachment; filename=whatever_name_you_want.zip"

return response

Open the zip file in binary mode when creating the HttpResponse to avoid errors whith newline conversion:

folder_file = open(full_path, "rb")
        response = HttpResponse(FileWrapper(folder_file), content_type='application/zip')

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