Python zip a sub folder and not the entire folder path

谁说我不能喝 提交于 2019-12-03 13:08:09

You'll have to give an arcname argument to ZipFile.write() that uses a relative path. Do this by giving the root path to remove to makeArchive():

def makeArchive(fileList, archive, root):
    """
    'fileList' is a list of file names - full path each name
    'archive' is the file name for the archive with a full path
    """
    a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)

    for f in fileList:
        print "archiving file %s" % (f)
        a.write(f, os.path.relpath(f, root))
    a.close()

and call this with:

makeArchive(dirEntries(folder, True), zipname, folder)

I've removed the blanket try:, except:; there is no use for that here and only serves to hide problems you want to know about.

The os.path.relpath() function returns a path relative to root, effectively removing that root path from the archive entry.

On python 2.5, the relpath function is not available; for this specific usecase the following replacement would work:

def relpath(filename, root):
    return filename[len(root):].lstrip(os.path.sep).lstrip(os.path.altsep)

and use:

a.write(f, relpath(f, root))

Note that the above relpath() function only works for your specific case where filepath is guaranteed to start with root; on Windows the general case for relpath() is a lot more complex. You really want to upgrade to Python 2.6 or newer if at all possible.

ZipFile.write has an optional argument arcname. Use this to remove parts of the path.

You could change your method to be:

def makeArchive(fileList, archive, path_prefix=None):
    """
    'fileList' is a list of file names - full path each name
    'archive' is the file name for the archive with a full path
    """
    try:
        a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)

        for f in fileList:
            print "archiving file %s" % (f)
            if path_prefix is None:
                a.write(f)
            else:
                a.write(f, f[len(path_prefix):] if f.startswith(path_prefix) else f)
        a.close()
        return True
    except: return False 

Martijn's approach using os.path is much more elegant, though.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!