简体   繁体   中英

Exclude a directory from getting zipped using zipfile module in python

I am trying to zip a directory using python zipfile module and its working well.But now i want to exclude some folders.ie if my director tree is like

abc
def
ghi
jkl
mno

then i want to archive all to myfile.zip but excluding "ghi"

I am trying to zip files using

zf = zipfile.ZipFile("Application server.zip", "w")
for dirname, subdirs, files in os.walk("D:\\review docs"):
    zf.write(dirname)
    for filename in files:
        zf.write(os.path.join(dirname, filename))
zf.close()

so this is archiving everything under "D:\\review docs" to "Application server.zip" but i want to exclude some directories from the zip. In fact i can use linux commands to do the same but i want to use zipfile module. Also if i pop exclude folder name from "dirname" list optained from os.walk,will that work? further Adding up a check before zipping like if "dirname"=="exlude folder" will also work i think but i want a neat solution of doing the same using the module.I read some where that zipfile module provides this functionality but didn't found any code example for the same.

Yes , you can remove elements from the subdirs , that would make sure that os.walk() does not into those directories. Example -

for dirname, subdirs, files in os.walk("D:\\review docs"):
    if 'exclude directory' in subdirs:
        subdirs.remove('exclude directory')
    zf.write(dirname)
    for filename in files:
        zf.write(os.path.join(dirname, filename))
zf.close()

I wrote a more complete version, which being able to filter folders and exts

We can't simply delete the folder like .svn before zipping. The following code can help.

It zips a folder to a zip file, maintaining its structure and filtering certain folders and exts, like what you expect natually.

def IsPathValid(path, ignoreDir, ignoreExt):
    splited = None
    if os.path.isfile(path):
        if ignoreExt:
            _, ext = os.path.splitext(path)
            if ext in ignoreExt:
                return False

        splited = os.path.dirname(path).split('\\/')
    else:
        if not ignoreDir:
            return True
        splited = path.split('\\/')

    for s in splited:
        if s in ignoreDir:  # You can also use set.intersection or [x for],
            return False

    return True

def zipDirHelper(path, rootDir, zf, ignoreDir = [], ignoreExt = []):
    # zf is zipfile handle
    if os.path.isfile(path):
        if IsPathValid(path, ignoreDir, ignoreExt):
            relative = os.path.relpath(path, rootDir)
            zf.write(path, relative)
        return

    ls = os.listdir(path)
    for subFileOrDir in ls:
        if not IsPathValid(subFileOrDir, ignoreDir, ignoreExt):
            continue

        joinedPath = os.path.join(path, subFileOrDir)
        zipDirHelper(joinedPath, rootDir, zf, ignoreDir, ignoreExt)

def ZipDir(path, zf, ignoreDir = [], ignoreExt = []):
    rootDir = path if os.path.isdir(path) else os.path.dirname(path)
    zipDirHelper(path, rootDir, zf, ignoreDir, ignoreExt)
    pass

use it like this:

import zipfile
theZipFile = zipfile.ZipFile(targetZipFile, 'w')
Util.ZipDir(target_dir, theZipFile, ignoreDir=[".svn"], ignoreExt=[".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