Search code examples
pythonzipshutil

Zip each folder (directory) recursively


I am trying to zip each folder on its own in Python. However, the first folder is being zipped and includes all folders within it. Could someone please explain what is going on? Should I not be using shutil for this?

#%% Set path variable
path = r"G:\Folder"
os.chdir(path)
os.getcwd()

#%% Zip all folders
def retrieve_file_paths(dirName):
    # File paths variable
    filePaths = []
    
    # Read all directory, subdirectories and file lists
    for root, directories, files in os.walk(dirName):
        for filename in directories:
            # Createthe full filepath by using os module
            filePath = os.path.join(root, filename)
            filePaths.append(filePath)
            
    # return all paths
    return filePaths

filepaths = retrieve_file_paths(path)

#%% Print folders and start zipping individually
for x in filepaths:
    print(x)
    shutil.make_archive(x, 'zip', path)

Solution

  • shutil.make_archive will make an archive of all files and subfolders - since this is what most people want. If you need more choice of what files are included, you must use zipfile directly.

    You can do this right within the walk loop (that is what it's for).

    import os
    import zipfile
    dirName = 'C:\...'
    # Read all directory, subdirectories and file lists
    for root, directories, files in os.walk(dirName):
         zf = zipfile.ZipFile(os.path.join(root, "thisdir.zip"), "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9)
         for name in files:
             if name == 'thisdir.zip': continue
             filePath = os.path.join(root, name)
             zf.write(filePath, arcname=name)
         zf.close()
    

    This will create a file "thisdir.zip" in each subdirectory, containing only the files within this directory.

    (edit: tested & corrected code example)