如何使用Python递归压缩文件夹?
在日常开发中,我们经常会需要将文件夹中的文件压缩为一个zip文件,以方便传输或存储等操作。在Python中,我们可以使用ZipFile库来实现这一操作。本文将介绍如何使用Python递归压缩文件夹,并附上示例代码。
阅读更多:Python 教程
压缩文件夹
在开始编写代码前,我们先来了解一下ZipFile库的常用方法:
- ZipFile(file, mode=’r’, compression=ZIP_STORED, allowZip64=True):初始化一个ZipFile对象,file为要创建的zip文件名,mode为访问模式,compression为压缩方式,默认为ZIP_STORED不压缩,allowZip64表示是否允许使用ZIP64扩展。
-
write(filename, arcname=None, compress_type=None, compresslevel=None):将filename文件添加到zip文件中,arcname为添加到zip文件中的文件名,省略时为filename,compress_type为压缩方式,省略时为ZIP_STORED,compresslevel为压缩级别,默认为最高级。
-
close():关闭ZipFile对象。
有了这些基本的操作方法,我们就可以开始编写代码了。下面是一个递归压缩文件夹的示例代码。
import os
import zipfile
def zip_folder(folder_path, zip_path):
"""
递归压缩文件夹
:param folder_path: 要压缩的文件夹路径
:param zip_path: 压缩后的zip文件路径
"""
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(folder_path):
for file in files:
zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file),
os.path.join(folder_path, '..')))
代码中,我们创建了一个名为zip_folder
的函数,它接受两个参数:要压缩的文件夹路径和压缩后的zip文件路径。在函数中,我们使用了with
语句打开了一个ZipFile对象,并指定访问模式为写入模式,并指定压缩方式为zipfile.ZIP_DEFLATED
。
然后,我们使用os.walk
函数递归遍历了文件夹中的所有文件,通过ZipFile对象的write
方法将文件一个一个添加到zip文件中。在写入文件时,我们使用了os.path.join
函数将文件的路径拼接为绝对路径,并使用os.path.relpath
函数将其转换为相对于文件夹路径的相对路径,方便后续的解压缩操作。
最后,在函数结尾处,我们使用了close
方法关闭了ZipFile对象。
解压缩文件夹
在压缩文件夹之后,我们当然也需要将其解压缩。ZipFile库也提供了相应的解压缩方法,下面是一个解压缩zip文件的示例代码。
import zipfile
def unzip_file(zip_path, dest_path):
"""
解压缩zip文件
:param zip_path: 要解压缩的zip文件路径
:param dest_path: 解压缩后的文件夹路径
"""
with zipfile.ZipFile(zip_path) as zipf:
zipf.extractall(dest_path)
代码中,我们创建了一个名为unzip_file
的函数,它接受两个参数:要解压缩的zip文件路径和解压缩后的文件夹路径。在函数中,我们使用了with
语句打开了一个ZipFile对象,并指定访问模式为默认模式。然后,我们使用extractall
方法将所有文件解压缩到指定的文件夹路径下。
测试代码
完成了压缩和解压缩的代码后,我们需要对其进行测试,以确保其正确性。下面是一个测试代码的示例。
import os
def test_zip_unzip():
folder_path = './test_folder'
zip_path = 'test.zip'
unzip_path = './unzip_folder'
# 创建测试文件夹和文件
if not os.path.exists(folder_path):
os.makedirs(folder_path)
file1 = open(os.path.join(folder_path, 'file1.txt'), 'w')
file1.write('This is file1.')
file1.close()
sub_folder = os.path.join(folder_path, 'sub_folder')
os.makedirs(sub_folder)
file2 = open(os.path.join(sub_folder, 'file2.txt'), 'w')
file2.write('This is file2.')
file2.close()
# 压缩测试文件夹
zip_folder(folder_path, zip_path)
# 解压缩压缩后的文件
unzip_file(zip_path, unzip_path)
# 对比原始文件夹和解压缩后的文件夹
for root, dirs, files in os.walk(folder_path):
for file in files:
with open(os.path.join(root, file), 'r') as f1, \
open(os.path.join(unzip_path, os.path.relpath(os.path.join(root, file), folder_path)), 'r') as f2:
assert f1.read() == f2.read()
# 删除测试文件夹、压缩文件和解压缩后的文件夹
os.removedirs(folder_path)
os.remove(zip_path)
for root, dirs, files in os.walk(unzip_path, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(unzip_path)
if __name__ == '__main__':
test_zip_unzip()
在上述测试代码中,我们创建了一个名为test_zip_unzip
的函数,在函数中进行了文件夹压缩、解压缩和对比三个步骤。其中,我们首先在当前目录下创建了一个名为test_folder
的测试文件夹,并在其中创建了两个文件file1.txt
和file2.txt
,以及一个子文件夹sub_folder
,并在其中创建了一个文件file2.txt
。
然后,我们使用zip_folder
函数将测试文件夹压缩为名为test.zip
的zip文件,再使用unzip_file
函数将zip文件解压缩到当前目录下的名为unzip_folder
的文件夹中。
最后,我们使用assert
语句对比原始文件夹和解压缩后的文件夹中的每个文件的内容是否相同,如果不相同,就会抛出异常。
结论
使用Python递归压缩文件夹只需要几行代码,可以大大提高我们工作的效率,减少手动操作的出错率。同时,在使用时我们也要注意对应用场景的调整和优化,以达到更好的效果。