python zip打包压缩和解压文件
压缩
1、自定义公共函数zip_files_and_dirs
import os
import zipfile
# 递归检测文件文件是否存在,存在则重命名文件
def check_file_exists(check_file, original_file=None, num=1):
if os.path.exists(check_file):
original_file = original_file if original_file else check_file
_splitext = os.path.splitext(original_file)
new_file_name = _splitext[0] + str(num) + _splitext[1]
new_file_name = check_file_exists(new_file_name, original_file, num + 1)
return new_file_name
return check_file
def zip_files_and_dirs(file_path_list, target_dir=None, target_file_name=None):
# 确保目标目录存在
assert file_path_list, "zip_files_and_dirs fail. params file_path_list is blank."
if not target_dir:
dir_path = file_path_list[0]
target_dir = os.path.dirname(dir_path)
if not target_file_name:
dir_path = os.path.splitext(file_path_list[0])[0]
target_file_name = os.path.basename(dir_path)
# 确保目标目录存在
if not os.path.exists(target_dir):
os.makedirs(target_dir)
# 创建zip文件的完整路径
zip_path = os.path.join(target_dir, f"{target_file_name}.zip")
zip_path = check_file_exists(zip_path) # 检测文件是否存在
# 创建zip文件
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in file_path_list:
if os.path.isfile(file_path):
# 如果是文件,直接添加到zip中
zipf.write(file_path, os.path.relpath(file_path, os.path.dirname(file_path)))
elif os.path.isdir(file_path):
# 如果是目录,递归添加目录及其子内容
for root, dirs, files in os.walk(file_path):
for file in files:
file_full_path = os.path.join(root, file)
arcname = os.path.relpath(file_full_path, os.path.dirname(file_path))
zipf.write(file_full_path, arcname)
# 确保即使目录为空也被添加
if not files and not dirs:
arcname = os.path.relpath(root, os.path.dirname(file_path)) + '/'
zipf.writestr(arcname, '')
return zip_path
if __name__ == '__main__':
# 存放目录或文件的列表
_file_path_list = [r'D:\ljh\project\test\test_path\new', // 存有子文件和子目录
r'D:\ljh\project\test\test_path\test_dir', // 空目录
r'D:\ljh\project\test\test_path\docx_file.docx',
r'D:\ljh\project\test\test_path\test.txt']
_target_dir = r'D:\ljh\project\test\test_path\target_dir' //压缩后目标目录
_zip_path = zip_files_and_dirs(_file_path_list, _target_dir, 'output') // 压缩打包, 'output'为压缩的文件名(output.zip)
print(f"ZIP 文件已创建:{_zip_path}")
2、输出结果:
ZIP 文件已创建:D:\ljh\project\test\test_path\target_dir\output.zip
解压
import os
import shutil
import zipfile
def support_gbk(zip_file: zipfile.ZipFile):
name_to_info = zip_file.NameToInfo
# copy map first
for name, info in name_to_info.copy().items():
try:
real_name = name.encode('cp437').decode('gbk')
except Exception as _e:
_ = _e
real_name = name.encode('utf8').decode('utf8')
if real_name != name:
info.filename = real_name
del name_to_info[name]
name_to_info[real_name] = info
return zip_file
def unzip_files(file_zip_path):
save_path = os.path.dirname(file_zip_path)
dir_path = os.path.splitext(file_zip_path)[0]
if os.path.isdir(dir_path):
shutil.rmtree(dir_path)
with support_gbk(zipfile.ZipFile(file_zip_path)) as zip_ref:
zip_ref.extractall(save_path)
return save_path
if __name__ == '__main__':
_zip_file = r"D:\ljh\project\test\test_path\target_dir\output.zip"
_un_zip_path = unzip_files(_zip_file)
print(_un_zip_path)