需求:
将指定压缩的文件、目录,压缩至指定的zip文件。
zip文件不存在时创建改文件,存在时将文件、目录追加至压缩包。
代码实现:
import os
from zipfile import ZipFile
from loguru import logger
@logger.catch()
def add_obj_to_zipfile(zip_obj, zip_file, zip_sub_dir='.', zip_base_dir=None):
"""
将指定文件对象添加值压缩包
:param zip_obj: 指定文件对象,可以是文件、目录
:param zip_file: 压缩包文件
:param zip_base_dir: 文件的基础路径
:param zip_sub_dir: 存放值压缩包的指定目录层级。默认为压缩包的根目录
"""
def add_objs(files, zip_fp, sub_dir='.', base_dir=None):
for file in files:
if os.path.isfile(file):
if not base_dir:
cur_base_dir = os.path.basename(file)
else:
cur_base_dir = file.replace(base_dir, '')
arcname = os.path.join(sub_dir, cur_base_dir)
else:
arcname = sub_dir
logger.debug(f'文件 {file} 保存至压缩包 {arcname}')
zip_fp.write(file, arcname)
if os.path.exists(zip_file):
zip_fp = ZipFile(zip_file, mode='a')
logger.debug('追加文件至压缩包')
else:
zip_fp = ZipFile(zip_file, mode='w')
logger.debug('创建压缩包')
if os.path.isfile(zip_obj):
add_objs([zip_obj], zip_fp, zip_sub_dir, zip_base_dir)
else:
if zip_base_dir:
base_dir = zip_base_dir
else:
base_dir = os.path.dirname(zip_obj)
for folder_name, sub_folders, files in os.walk(zip_obj):
sub_dir = folder_name.replace(base_dir, '')
add_objs([folder_name], zip_fp, sub_dir=sub_dir, base_dir=base_dir)
logger.debug(f'添加目录 {sub_dir}')
files_path = [os.path.join(folder_name, file) for file in files]
add_objs(files_path, zip_fp, sub_dir=sub_dir, base_dir=base_dir)
logger.debug(f'{sub_dir} 添加文件 {files}')
zip_fp.close()
logger.info(f'压缩 {zip_obj} 至 {zip_file}')