Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a zip file of a file path using Python, including empty directories?

Tags:

python

zip

shutil

I've been trying to use the zipfile and shutil.make_archive modules to recursively create a zip file of a directory. Both modules work great--except empty directories do not get added to the archive. Empty directories containing other empty directories are also silently skipped.

I can use 7Zip to create an archive of the same path and empty directories are preserved. Therefore I know this is possible within the file format itself. I just don't know how to do it within Python. Any ideas? Thanks!

like image 825
jamieb Avatar asked Aug 01 '12 02:08

jamieb


People also ask

How do I zip multiple folders in Python?

Create a zip archive from multiple files in PythonCreate a ZipFile object by passing the new file name and mode as 'w' (write mode). It will create a new zip file and open it within ZipFile object. Call write() function on ZipFile object to add the files in it. call close() on ZipFile object to Close the zip file.

How do I compress a directory in Python?

When compressing an entire directory (folder) into a zip file in Python, you can use os. scandir() or os. listdir() to create a list of files and use the zipfile module to compress them, but it is easier to use the make_archive () of the shutil module is easier.

Which statement successfully creates a zip file using the ZipFile module in Python?

To work on zip files using python, we will use an inbuilt python module called zipfile. print ( 'Done!' )


2 Answers

There is a example using zipfile:

import os, zipfile  
from os.path import join  
def zipfolder(foldername, filename, includeEmptyDIr=True):   
    empty_dirs = []  
    zip = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED)  
    for root, dirs, files in os.walk(foldername):  
        empty_dirs.extend([dir for dir in dirs if os.listdir(join(root, dir)) == []])  
        for name in files:  
            zip.write(join(root ,name))  
        if includeEmptyDIr:  
            for dir in empty_dirs:  
                zif = zipfile.ZipInfo(join(root, dir) + "/")  
                zip.writestr(zif, "")  
        empty_dirs = []  
    zip.close() 

if __name__ == "__main__":
    zipfolder('test1/noname/', 'zip.zip')
like image 66
iceout Avatar answered Sep 21 '22 12:09

iceout


You'll need to register a new archive format to do that, since the default ZIP archiver does not support that. Take a look at the meat of the existing ZIP archiver. Make your own archiver that creates directories using that currently-unused dirpath variable. I looked for how to create an empty directory and found this:

zip.writestr(zipfile.ZipInfo('empty/'), '')

With that, you should be able to write the necessary code to make it archive empty directories.

like image 23
icktoofay Avatar answered Sep 22 '22 12:09

icktoofay