Python ZIP压缩文件夹

直接上代码,仅做学习笔记用,核心代码bak_one_dir_by_zip函数 try-except内

#! /usr/bin/python # -*- coding: utf-8 -*
import logging
import os, sys
import zipfile
import time
import traceback
import re
import subprocess  #获取命令行输出的结果
#LOG_FORMAT = "%(asctime)s %(name)s %(levelname)s %(pathname)s %(message)s "#配置输出日志格式
LOG_FORMAT = "%(message)s " #简要的格式,只包含输入文本
DATE_FORMAT = '%Y-%m-%d  %H:%M:%S %a ' #配置输出时间的格式,注意月份和天数不要搞乱了
LOG_PATH = os.path.join(os.getcwd(),'bak_coll_app.log')
logging.basicConfig(level=logging.DEBUG,
                    format=LOG_FORMAT,
                    datefmt = DATE_FORMAT ,
                    filemode='w', #覆盖之前的记录 'a'是追加
                    filename=LOG_PATH #有了filename参数就不会直接输出显示到控制台,而是直接写入文件
                    )

ROOT_PATH='/home/jzcj'
BACK_APPS=['tomcat', 'titan', 'antab', 'agent', 'src']

#压缩单个目录,注意入参需要时绝对路径,是否按绝对路径压缩,建议选按相对路径压缩,即isAbs = False
def bak_one_dir_by_zip(folder, isAbs):
    folder = os.path.abspath(folder)    #make sure folder is abslote
    #get current time by yyyymmdd format
    date_ymd=time.strftime('%Y%m%d',time.localtime(time.time()))
    number = 1
    while True:
        zipFilename = os.path.basename(folder) + '_' + date_ymd + '_' + str(number) +'.zip' 
        #basename是最后一个斜杠后的字符串,dirname是最后一个斜杠钱的字符串
        if not os.path.exists(zipFilename):
            break
        number += 1
 
    #create zipfile
    print('Try create %s and adding  files...' %(zipFilename))
    logging.debug('Try create %s and adding  files...' %(zipFilename))
    # can user with-as too ??
    backupzip = zipfile.ZipFile(zipFilename, 'w',zipfile.ZIP_STORED,allowZip64=True)
    '''
    zf = zipfile.ZipFile(zipfilename, "w", zipfile.ZIP_STORED,allowZip64=True)
    四个参数:zip文件包含路径的名字,"w"/"r"表示写或者读,zipfile.ZIP_STORED表示存储格式(还可以是zipfile.zlib.DEFLATED表示压缩格式),
    allowZip64=True这个参数是在处理大文件时使用的,默认为False。如果没有设置为True而处理大文件时会提示 zip file size require ZIP64 extensions.
    '''
    #正则表达式排除日志记录文件
    exfile1 = re.compile(r'(.*)?(\.log)$')
    exfile2 = re.compile(r'^(log\.)(.*)?')
    exfile3 = re.compile(r'(.*)\.log\.(.*)')
    exfile4 = re.compile(r'snapshot(.*)')
    try:
        #list all dir and zip to zipfile
        #walk the entire folder tree and compress the files in each folder
        for foldeName, subfolders, fileNames in os.walk(folder):
            #Add the current  folder to the ZIP file
            if True == isAbs:
                backupzip.write(foldeName)
            else:
                #相对路径压缩,而不是绝对路径
                fpath = foldeName.replace(folder, '')
                #下面这句很必要,需要理解,如果当前目录替换了根目录就是空值‘’,那么说明当前目录为一级或最外围目录,
                #如果不是'',说明当前目录是下一层子目录,则对子目录添加系统的分隔符
                #如果不加这一句,将会把所有文件压缩到根目录下
                fpath = fpath and fpath + os.sep or '' 
                #python里面,0、’’、[]、()、{}、None为假,其它任何东西都为真
                # (对于or,如果没有真值,返回的是最后一个假值,如果有真值,则返回的是第一个真值。)
                # (对于and,如果没有假值,返回的是最后一个真值,如果有假值,则返回的是第一个假值。)

            #Add all the files in this folder to the ZIP file
            for filename in fileNames:
                #正则表达排除log日志文件
                if (None != exfile1.search(filename) or \
                    None != exfile2.search(filename) or \
                    None != exfile3.search(filename) or \
                    None != exfile4.search(filename)
                    ):
                    logging.debug('In forlder %s current file is %s , and no need to compress,continue...' \
                     %(foldeName, filename))
                    continue #跳过以下所有步骤,进行下一个文件压缩
                else:
                    logging.debug('Adding zipfiles from file %s/%s...' %(foldeName, filename))
                    newBase = os.path.basename(folder) + '_'
                    if filename.startswith(newBase) and filename.endswith('.zip'):
                        continue #不备份之前的备份压缩文件
                    if True == isAbs:
                        #以绝对路径压缩
                        backupzip.write(os.path.join(foldeName, filename))
                        #backupzip.write(os.sep.join([foldeName, filename]))
                    else:
                        #相对路径压缩而不是绝对路径
                        backupzip.write(os.path.join(foldeName, filename),fpath+filename)
                        #backupzip.write(os.sep.join([foldeName, filename]),fpath+filename) #os.sep 操作系统文件夹分割符 /或\\
    except:
        logging.debug('in zipfile %s , some error happend,trace-info like: %s ' %(zipFilename, traceback.format_exc()))
        logging.debug('some bad things happend, close backupzip and return.')
        print('some bad things happend, close backupzip and return.')
        backupzip.close()
        return None
    
    #zipfile write success normal finished
    backupzip.close()
    print('zip %s Done!' %(zipFilename))
    logging.debug('zip %s Done!' %(zipFilename))
    return None

#调用bak_one_dir_by_zip 逐个文件夹压缩
def bak_all_dir():
    abs_bak_path = []
    for app_name in BACK_APPS:
        abs_bak_path.append(os.path.join(ROOT_PATH, app_name))
        #删除旧的备份文件
    for app in abs_bak_path:
        if os.path.exists(app):
            bak_one_dir_by_zip(app,False)
        else:
            print('No such path or file:%s.' %(app))

def call_shell_rm_old():
    zipfile = []
    for app_name in BACK_APPS:
        shell_cmd = 'rm -rf ' + app_name + '*.zip'
        print('excute shell_cmd = %s' %(shell_cmd))
        try:
            subpip = subprocess.Popen(shell_cmd, shell=True,stdout=subprocess.PIPE) #将命令行输出的结果写入PIPE
            #re = os.system(doredis)
        except:
            logging.debug('some error happedn in delete %s*.zip ,trace-info like: %s ' \
                 %(app_name, traceback.format_exc()))

    return None

if __name__=='__main__':
    #调用系统命令行删除旧的备份文件
    call_shell_rm_old()
    bak_all_dir()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值