递归压缩每个文件夹(目录)

Zip each folder (directory) recursively

我正在尝试将每个文件夹单独压缩到 Python 中。但是,第一个文件夹正在压缩并包含其中的所有文件夹。有人可以解释一下发生了什么吗?我不应该为此使用 shutil 吗?

#%% 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)

一旦您查看 Docs,这是一个相对简单的答案。

您可以在shutil.make_archive下看到以下内容: Note This function is not thread-safe.

计算中的线程在高层次上的工作方式: 机器上有内核,可以处理数据。 (例如 AMD Ryzen 5 5800x 8 核) 在一个进程中,有线程(例如 Ryzen 5800X 上有 16 个线程)。

但是,在多进程中,进程之间不共享数据。 在一个进程内的多线程中,您可以从同一变量访问数据。

由于此函数不是线程安全的,您将共享变量“x”并访问相同的项目。这意味着只能有一个输出。

查看多线程并使用锁来对线程进行后续处理。

干杯

shutil.make_archive 将对所有文件和子文件夹进行归档 - 因为这是大多数人想要的。如果您需要更多选择包含哪些文件,您必须直接使用 zipfile

您可以在 walk 循环中执行此操作(这就是它的用途)。

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

这将在每个子目录中创建一个文件“thisdir.zip”,仅包含该目录中的文件。

(编辑:经过测试和更正的代码示例)

根据 Torben 对我的问题的回答,我修改了代码以递归地压缩每个目录。我意识到发生的事情是我没有指定子目录。代码如下:

#Set path variable
path = r"insert root directory here"
os.chdir(path)

# Declare the functionto return all file paths in selected directory
def retrieve_file_paths(dirName):
   for root, dirs, files in os.walk(dirName):
       for dir in dirs:
        zf = zipfile.ZipFile(os.path.join(root+dir, root+dir+'.zip'), "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9)
        files = os.listdir(root+dir)
        print(files)
        filePaths.append(files)
        for f in files:
            filepath = root + dir +'/'+ f
            zf.write(filepath, arcname=f)
        zf.close()

retrieve_file_paths(path)