Python中带有子文件夹的ZIP文件夹

12

我需要使用Python压缩一个包含.xml文件和.fgdb文件的文件夹,请问有人可以帮助我吗?我尝试了一些在互联网上找到的脚本,但总是会出现一些技术问题(比如创建一个空的zip文件,或者创建我无法打开“没有权限”的zip文件等)。

先行致谢。

3个回答

24

让它工作的关键是使用os.walk()函数。 这是我以前组装的应该可以工作的脚本。 如果你遇到任何异常,请让我知道。

import zipfile
import os
import sys

def zipfolder(foldername, target_dir):            
    zipobj = zipfile.ZipFile(foldername + '.zip', 'w', zipfile.ZIP_DEFLATED)
    rootlen = len(target_dir) + 1
    for base, dirs, files in os.walk(target_dir):
        for file in files:
            fn = os.path.join(base, file)
            zipobj.write(fn, fn[rootlen:])

zipfolder('thenameofthezipfile', 'thedirectorytobezipped') #insert your variables here
sys.exit()

好的。首先帮我一下,那个目标文件夹(target_dir)和文件夹名称(foldername)是什么?请给我一个例子,以确保我理解正确。因为我尝试了你的代码,它没有出现异常,但也没有创建压缩文件! - Z77
1
我必须道歉。代码是有效的。Zip文件实际上是在保存.py文件的文件夹中创建的。我没有注意到fn[rootlen:]。非常感谢!!! - Z77
1
FYI,我爱你。在尝试了大约4天后,这个方法第一次就奏效了。诀窍是跳过一个文件夹,以便不包括顶级目录。 - trench
没问题,很高兴能帮忙 :) - James Milner
我曾经花费无数个小时尝试从压缩状态中让我的epub文件工作。在fedora系统中,原生的压缩导致epub文件无法读取。但通过您提供的方法,我终于可以将我的电子书写入zip并将其转换为epub文件。您是我的英雄。 - Leon Beckert
显示剩余4条评论

3

这个答案非常有帮助,但是我需要一点时间才能完全理解rootlen的作用。这个例子使用了一些较长的变量名来帮助教授确切的情况。同时还包括一个块以验证压缩文件是否正确。

import os
import zipfile

src_path = os.path.join('/', 'some', 'src', 'path')
archive_name = 'myZipFile.zip'
archive_path = os.path.join('/', 'some', 'path', archive_name)

with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as archive_file:
    for dirpath, dirnames, filenames in os.walk(src_path):
        for filename in filenames:
            file_path = os.path.join(dirpath, filename)
            archive_file_path = os.path.relpath(file_path, src_path)
            archive_file.write(file_path, archive_file_path)

with zipfile.ZipFile(archive_path, 'r') as archive_file:
    bad_file = zipfile.ZipFile.testzip(archive_file)

    if bad_file:
        raise zipfile.BadZipFile(
            'CRC check failed for {} with file {}'.format(archive_path, bad_file))

0
如果有人想在项目中使用一些通用函数。
def zip_compression_tree(root_path, zip_name):
with zipfile.ZipFile(zip_name, 'w') as z:
    for root, dirs, files in os.walk(root):
        for file in files:
            z.write(os.path.join(root, file))
        for directory in dirs:
            z.write(os.path.join(root, directory))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接