Python压缩子文件夹而不是整个文件夹路径 [英] Python zip a sub folder and not the entire folder path

查看:55
本文介绍了Python压缩子文件夹而不是整个文件夹路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序可以压缩文件夹中的所有内容.我没有写这段代码,但我在网上找到了它,我正在使用它.我打算压缩一个文件夹,例如 C:/folder1/folder2/folder3/.我想将 folder3 及其所有内容压缩到一个文件中,例如 folder3.zip.使用下面的代码,一旦我压缩它,folder3.zip 的内容将是 folder1/folder2/folder3/and files.我不希望压缩整个路径,我只希望压缩我感兴趣的子文件夹(在这种情况下为文件夹 3).我尝试了一些 os.chdir 等,但没有运气.

I have a program to zip all the contents in a folder. I did not write this code but I found it somewhere online and I am using it. I intend to zip a folder for example say, C:/folder1/folder2/folder3/ . I want to zip folder3 and all its contents in a file say folder3.zip. With the below code, once i zip it, the contents of folder3.zip wil be folder1/folder2/folder3/and files. I do not want the entire path to be zipped and i only want the subfolder im interested to zip (folder3 in this case). I tried some os.chdir etc, but no luck.

def makeArchive(fileList, archive):
    """
    '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)
            a.write(f)
        a.close()
        return True
    except: return False 

def dirEntries(dir_name, subdir, *args):
    # Creates a list of all files in the folder
    '''Return a list of file names found in directory 'dir_name'
    If 'subdir' is True, recursively access subdirectories under 'dir_name'.
    Additional arguments, if any, are file extensions to match filenames. Matched
        file names are added to the list.
    If there are no additional arguments, all files found in the directory are
        added to the list.
    Example usage: fileList = dirEntries(r'H:\TEMP', False, 'txt', 'py')
        Only files with 'txt' and 'py' extensions will be added to the list.
    Example usage: fileList = dirEntries(r'H:\TEMP', True)
        All files and all the files in subdirectories under H:\TEMP will be added
        to the list. '''

    fileList = []
    for file in os.listdir(dir_name):
        dirfile = os.path.join(dir_name, file)
        if os.path.isfile(dirfile):
            if not args:
                fileList.append(dirfile)
            else:
                if os.path.splitext(dirfile)[1][1:] in args:
                    fileList.append(dirfile)
            # recursively access file names in subdirectories
        elif os.path.isdir(dirfile) and subdir:
            print "Accessing directory:", dirfile
            fileList.extend(dirEntries(dirfile, subdir, *args))
    return fileList

您可以通过 makeArchive(dirEntries(folder, True), zipname) 调用它.

You can call this by makeArchive(dirEntries(folder, True), zipname).

关于如何解决这个问题的任何想法?我正在使用 Windows 操作系统和 python 25,我知道在 python 2.7 中有 Shutil make_archive 有帮助,但由于我正在使用 2.5,我需要另一个解决方案:-/

Any ideas as to how to solve this problem? I am uing windows OS annd python 25, i know in python 2.7 there is shutil make_archive which helps but since i am working on 2.5 i need another solution :-/

推荐答案

你必须给 ZipFile.write() 使用相对路径.通过将要删除的根路径提供给 makeArchive() 来执行此操作:

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()

并调用它:

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

我已经删除了毯子 try:, except:;在这里没有任何用处,只会隐藏您想了解的问题.

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.

os.path.relpath() 函数返回相对于 root 的路径,有效地从存档条目中删除该根路径.

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

在python 2.5上,relpath函数不可用;对于此特定用例,以下替换将起作用:

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)

并使用:

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

请注意,上述 relpath() 函数仅适用于您保证 filepathroot 开头的特定情况;在 Windows 上,relpath() 的一般情况要复杂得多.如果可能,您确实想升级到 Python 2.6 或更高版本.

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.

这篇关于Python压缩子文件夹而不是整个文件夹路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆