Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - error when zipping files, 'L' format requires 0 <= number <= 4294967295

I run this code for zipping folders and files.

def save_folder_as_zip(self, folder_to_zip, save_as):
    zipf = zipfile.ZipFile(str(save_as), mode="w", allowZip64=True)
    self.create_zip(zipf, folder_to_zip)
    zipf.close()

    return zipf

def create_zip(self, zipf, directory, folder=""):

    directory = directory.encode("utf-8")

    for item in os.listdir(directory):
        if temp_folder == directory + os.sep:
            continue

        try:
            if os.path.isfile(os.path.join(directory, item)):
                zipf.write(os.path.join(directory, item), folder + os.sep + item)
            elif os.path.isdir(os.path.join(directory, item)):
                self.create_zip(zipf, os.path.join(directory, item).decode("utf-8"), folder + os.sep + item)
        except Exception, e:
            self.schedule.machine.log_warning(str(e))

But then I get this error:

'L' format requires 0 <= number <= 4294967295

Example on filename where this happens:

/[Wii]TrackMania[PAL][WiiSOS.com]/ws_tramap.iso

Any ideas how I can fix this?

Traceback:

Traceback (most recent call last):
File "test.py", line 29, in <module>
   save_folder_as_zip("/Users/f/Downloads/", "hei.zip")
File "test.py", line 13, in save_folder_as_zip
   create_zip(zipf, folder_to_zip)
File "test.py", line 26, in create_zip
   create_zip(zipf, os.path.join(directory, item).decode("utf-8"), folder + os.sep + item)  
File "test.py", line 24, in create_zip
   zipf.write(os.path.join(directory, item), folder + os.sep + item)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/zipfile.py", line 1100, in write
   zinfo.file_size))
struct.error: 'L' format requires 0 <= number <= 4294967295
like image 250
Aola Avatar asked Aug 02 '11 12:08

Aola


1 Answers

I think it can be fixed applying the patch attached to this bug report:

http://bugs.python.org/issue9720

The problem arises when the file you are trying to include in the zip file is larger than 2^32-1 bytes in original or compressed form. In this scenario the library need to store -1 as the file size/compressed size and has to allocate some extra fields to store the actual size, which does not fit in a 32-bit dword.

For some reason the patch has not been accepted in 3.2 or 2.7.2+, but I have tested it and it works OK. I think it does not fix some corner case with writestr() method, but if you only use write() to store files it works great.

like image 124
enlavin Avatar answered Oct 23 '22 18:10

enlavin