Python全能压缩:ZIP的压缩、解压、文件筛选与删除,一键搞定!

liftword2个月前 (03-03)技术文章22

引言:

这个方法实现了文件压缩与解压的常见操作,涵盖内容如下:

1、从文件夹创建 ZIP 文件

2、从文件夹创建 ZIP 文件(筛选特定文件)

3、解压 ZIP 文件中的所有内容

4、解压 ZIP 文件中的特定文件(筛选文件)

5、向现有 ZIP 文件中添加文件

6、从 ZIP 文件中删除文件

代码封装如下:

import os
import zipfile

class ZipFileManager:
    def __init__(self, file_path=None, unzip_file_path=None, zip_path=None):
        self.file_path = file_path   #todo 压缩源文件夹路径
        self.unzip_file_path = unzip_file_path  #todo 解压目标 ZIP 文件路径
        self.zip_path = zip_path  #todo 要操作的现有 ZIP 文件路径

    def create_zip_from_folder(self, zip_file_path):
        #todo 打开一个新的 zip 文件,使用 'w' 模式表示写入(会覆盖已存在的文件)
        with zipfile.ZipFile(zip_file_path + '.zip', 'w', zipfile.ZIP_DEFLATED) as zip_ref:
            #todo 遍历文件夹中的所有文件
            for root, _, files in os.walk(self.file_path):
                for file in files:
                    #todo 获取每个文件的完整路径
                    path = os.path.join(root, file)
                    #todo 获取文件的相对路径
                    arc_name = os.path.relpath(path, self.file_path)
                    #todo 将文件写入 ZIP 文件,arc_name 是文件在压缩包中的路径
                    zip_ref.write(path, arc_name)

    def create_zip_from_folder_with_special_files(self, zip_file_path, file_names=None, file_extensions=None):
        with zipfile.ZipFile(zip_file_path + '.zip', 'w', zipfile.ZIP_DEFLATED) as zip_ref:
            for root, _, files in os.walk(self.file_path):
                for file in files:
                    path = os.path.join(root, file)
                    file_name = os.path.basename(file)
                    #todo 如果指定了文件名,并且文件名不在列表中,则跳过该文件
                    if file_names and file_name not in file_names:
                        continue
                    #todo 如果指定了文件扩展名,并且文件的扩展名不符合,则跳过该文件
                    if file_extensions and not any(file.endswith(ext) for ext in file_extensions):
                        continue
                    #todo 获取文件的相对路径
                    arc_name = os.path.relpath(path, self.file_path)
                    #todo 将文件写入压缩包
                    zip_ref.write(path, arc_name)

    def extract_zip_all(self, extract_path):

        with zipfile.ZipFile(self.unzip_file_path, 'r') as zip_ref:
            zip_ref.extractall(extract_path)

    def extract_special_files_from_zip(self, extract_path, file_names=None, file_extensions=None):

        with zipfile.ZipFile(self.unzip_file_path, 'r') as zip_ref:
            #todo 遍历 ZIP 文件中的所有文件
            for file_info in zip_ref.infolist():
                #todo 如果指定了文件名,并且文件名不在列表中,则跳过该文件
                if file_names and file_info.filename not in file_names:
                    continue
                #todo 如果指定了文件扩展名,并且文件的扩展名不符合,则跳过该文件
                if file_extensions and not any(file_info.filename.endswith(ext) for ext in file_extensions):
                    continue
                #todo 解压符合条件的文件到指定路径
                zip_ref.extract(file_info, extract_path)

    def add_files_to_exist_zip(self, files_to_add, destination_folder=None):

        with zipfile.ZipFile(self.zip_path, 'a', zipfile.ZIP_DEFLATED) as zip_ref:
            for filepath in files_to_add:
                #todo 如果指定了目标文件夹,文件将在该文件夹内存储,否则直接保存文件
                arcname = os.path.join(destination_folder, os.path.basename(filepath)) if destination_folder else os.path.basename(filepath)
                #todo 将文件写入现有的 ZIP 文件
                zip_ref.write(filepath, arcname)

    def remove_files_from_zip(self, files_to_remove):
        files_to_remove = set(files_to_remove)  #todo 将待删除文件名列表转换为集合,确保唯一性
        temp_zip_file_path = self.zip_path + '.temp'  #todo 创建临时 ZIP 文件路径

        #todo 打开原 ZIP 文件和临时 ZIP 文件
        with zipfile.ZipFile(self.zip_path, 'r') as zip_ref, zipfile.ZipFile(temp_zip_file_path, 'w') as temp_zip_ref:
            for file_info in zip_ref.infolist():
                #todo 如果文件不在待删除列表中,则将文件写入临时 ZIP 文件
                if file_info.filename not in files_to_remove:
                    file_data = zip_ref.read(file_info.filename)
                    temp_zip_ref.writestr(file_info, file_data)

        #todo 用临时文件替换原 ZIP 文件
        os.replace(temp_zip_file_path, self.zip_path) 

if __name__ == '__main__':
    #todo 示例:创建一个 ZipFileManager 实例并执行相关方法
    file_path = r'D:\remote'  #todo 要压缩的文件夹路径
    zip_file_manager = ZipFileManager(file_path=file_path)
    
    #todo 创建 ZIP 文件,包含所有文件
    zip_file_manager.create_zip_from_folder(zip_file_path=r'D:\remote1')

    #todo 创建 ZIP 文件,包含特定文件名和扩展名的文件
    zip_file_manager.create_zip_from_folder_with_special_files(
        zip_file_path=r'D:\remote_special',
        file_names=['example.txt', 'test.pdf'],
        file_extensions=['.txt', '.pdf'])

其中需要的注意点:

路径格式:路径应使用合适的格式,确保在不同操作系统中路径分隔符正确。在 Windows 系统中路径使用反斜杠(\\ 或 /),而在 Linux 或 macOS 上使用正斜杠(/)。可以使用 os.path.join() 来确保跨平台兼容性。

权限问题:在读取或写入 ZIP 文件时,确保对目标文件有适当的读取或写入权限。如果文件正在被其他程序(如压缩软件)占用,可能会导致访问失败。

ZIP 文件的打开模式:打开 ZIP 文件时,确保使用正确的模式('r'、'w'、'a')

相关文章

最全RAR文件操作指南:如何用Python压缩、解压与筛选文件

引言:Python 对 .rar 文件进行压缩、解压以及筛选特定文件的操作代码封装一下import os import rarfile #todo 用于处理 RAR 文件 import zipfil...

20 天学 Python 文件操作:Day 16 文件压缩与解压

在日常工作中,我们经常需要对文件进行压缩和解压操作以减少存储空间或方便文件传输。今天,我们将学习如何使用 Python 进行文件的压缩与解压。1. 使用 zipfile 模块进行 ZIP 文件操作创建...

15《Python 办公自动化教程》文件压缩与解压缩

压缩包也是我们平时工作中经常要接触到的文件格式,压缩文件后缀名通常有 .zip、.rar、.7z 等等。Python 中也有专门用来操作压缩包文件的第三方模块 zipfile。听这个名字就知道是用来操...

python压缩/解压gzip 大文件

最近处理线上日志,日志文件刚好是经过压缩的,且是gz后缀。自己便采用gzip库来处理。示例如下:创建gzip文件# -- coding: utf-8 -- import gzip """ 创建gzi...

小明用Python暴力破解压缩文件zip密码,省了250块钱

那天晚上小明和你一样在某个小网站上搜寻某些私密的学习资料突然看到论坛有人提供了一个非常牛逼的资源小明怀着激动的心情下载了下来他怀着激动的心情打开了这个压缩文件看到就只有这么一个 txt 小明就是一顿双...