Is any way to split zip archive to sections?

Larry Bates larry.bates at websafe.com
Mon Apr 2 13:12:25 EDT 2007


Tim Williams wrote:
> On 30/03/07, Durumdara <durumdara at gmail.com> wrote:
>> Hi!
>>
>> I want to create some backup archives with python (I want to write a
>> backup
>> application in Python).
>> Some package managers (7z, arj, winzip) can create splitted archives (1
>> mega, 650, 700 mega, etc).
>>
>> Because I want to ftp these results to a ftp server, I want to split
>> large
>> volumes to 15 mb sections.
>>
>> Can I do it with any python wrapper automatically (like in Cobian), or I
>> need to create the large volume, and next split it with another tool?
>>
>> Or anybody knows about a command line tool (like 7z, or arj) that can
>> expand
>> the splitted archive (and I can add files with them from Python one by
>> one)?
>>
> 
> If you are iterating through a list of files to be backed up, and
> adding them to a ZIP one-by-one then you could use something like this
> which adds each file until the zip is over 15mb - then it closes the
> ZIP and creates the next one.
> 
> Not tested or optimised :)
> ---------------------------------------------------------------------------------------------------
> 
> import zipfile
> 
> archive_num = 1
> outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")
> zsize = 0
> 
> for full_name in filelist:
>    full_name_path = os.path.join(full_name, full_path)
> 
>    if zsize > 15728640 : # 15mb
>        outfile.close()
>        archive_num += 1
>        outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")
>        zsize= 0
> 
>    outfile.write( full_name_path , full_name_path ,
> zipfile.ZIP_DEFLATED) # add the file
>    zsize += outfile.getinfo(full_name_path).compress_size #  get
> compressed size of file
> 
> outfile.close()

You can do slightly better as following:

change to (not tested):


import os
import stat
import zipfile

archive_num = 1
outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")
zsize = 0

for full_name in filelist:
    full_name_path = os.path.join(full_name, full_path)
    if outfile.fp.tell() > 15728640: # 15mb
        outfile.close()
        archive_num += 1
        outfile = zipfile.ZipFile('/zips/archive%s.zip' % archive_num, "w")

    outfile.write(full_name_path,full_name_path,zipfile.ZIP_DEFLATED)


There is still a couple of "issues":

1) Files larger than 15Mb may not be able to be compressed to fall below the limit.

2) If you are near the 15Mb limit and the next file is very large you have the
same problem.


-Larry



More information about the Python-list mailing list