python 解压、复制文件

时间:2024-01-26 11:40:34

一、python3解压文件

1.python 解压文件代码示例

如下代码主要实现zip、rar、tar、tar.gz四种格式的压缩文件的解压


import os
import zipfile
import tarfile
from zipfile import ZipFile
from unrar import rarfile
def unzip_file(src_file, dst_dir=None, unzipped_files=None, del_flag=True):
    """
    根据指定的压缩文件类型递归解压所有指定类型的压缩文件
    :param src_file: 解压的源文件路径,可以为文件夹路径也可以是文件路径
    :param dst_dir: 解压后的文件存储路径
    :param unzipped_files: 完成解压的文件名列表
    :param del_flag: 解压完成后是否删除原压缩文件,默认删除
    :return: 完成解压的文件名列表
    """
    # 完成解压的文件名列表初始为空
    if unzipped_files is None:
        unzipped_files = []
    # 指定的解压文件类型
    zip_types = [\'.zip\', \'.rar\', \'.tar\', \'.gz\']

    def exec_decompress(zip_file, dst_dir):
        """
        解压实现的公共代码
        :param zip_file: 压缩文件全路径
        :param dst_dir: 解压后文件存储路径
        :return:
        """
        file_suffix = os.path.splitext(zip_file)[1].lower()
        try:
            print(\'Start extracting the file: %s\' % zip_file)

            # zip 解压
            if file_suffix == \'.zip\':
                # zip解压 写法一
                with ZipFile(zip_file, mode=\'r\') as zf:
                    zf.extractall(dst_dir)
                # zip解压 写法二
                # file_zip = ZipFile(zip_file, mode=\'r\')
                # for file in file_zip.namelist():
                #     file_zip.extract(file, dst_dir)
                # file_zip.close()

            # rar 解压
            elif file_suffix == \'.rar\':
                rf = rarfile.RarFile(zip_file)
                rf.extractall(dst_dir)

            # tar、tgz(tar.gz) 解压
            elif file_suffix in [\'.tar\', \'.gz\']:
                tf = tarfile.open(zip_file)
                tf.extractall(dst_dir)
                # 关闭文件释放内存
                tf.close()

            print(\'Finished extracting the file: %s\' % zip_file)
        except Exception as e:
            print(e)
        # 解压完成加入完成列表
        unzipped_files.append(zip_file)
        # 根据标识执行原压缩文件删除
        if del_flag and os.path.exists(zip_file):
            os.remove(zip_file)

    # 如果传入的文件路径为文件目录,则遍历目录下所有文件
    if os.path.isdir(src_file):
        # 初始化文件目录下存在的压缩文件集合为空
        zip_files = []
        # 如果传入的目的文件路径为空,则取解压的原文件夹路径
        dst_dir = dst_dir if dst_dir else src_file
        # 遍历目录下所有文件
        for file in os.listdir(src_file):
            file_path = os.path.join(src_file, file)
            # 如果是文件夹则继续递归解压
            if os.path.isdir(file_path):
                dst_path = os.path.join(dst_dir, file)
                unzip_file(file_path, dst_path, unzipped_files)
            # 如果是指定类型的压缩文件则加入到压缩文件列表
            elif os.path.isfile(file_path) and os.path.splitext(file_path)[
                1].lower() in zip_types and file_path not in unzipped_files:
                zip_files.append(file_path)
        # 遍历压缩文件列表,执行压缩文件的解压
        for zip_file in zip_files:
            exec_decompress(zip_file, dst_dir)
        # 如果当前目录存在压缩文件则完成所有文件解压后继续遍历
        if zip_files:
            unzip_file(dst_dir, unzipped_files=unzipped_files)
    # 如果传入的文件路径是指定类型的压缩文件则直接执行解压
    elif os.path.isfile(src_file) and os.path.splitext(src_file)[1].lower() in zip_types:
        dst_dir = dst_dir if dst_dir else os.path.dirname(src_file)
        exec_decompress(src_file, dst_dir)

    return unzipped_files

2.python解压常见问题解决办法

2.1 python3 zipfile解压文件名乱码解决办法

直接修改源码,即 zipfile.py 文件:

第一处:

if flags & 0x800:
    # UTF-8 file names extension
    filename = filename.decode(\'utf-8\')
else:
    # Historical ZIP filename encoding
    # 注释原代码
    # filename = filename.decode(\'cp437\')
    # 新加一行代码
    filename = filename.decode(\'gbk\')

 第二处:

if zinfo.flag_bits & 0x800:
    # UTF-8 filename
    fname_str = fname.decode("utf-8")
else:
    # 注释原代码
    # fname_str = fname.decode("cp437")
    # 同样新加一行代码
    fname_str = fname.decode(\'gbk\')

2.1 rar 解压无法找到动态库(unrar.dll)解决办法

报错示例:

第一步 手动下载动态库文件 unrar.dll 存在本地目录,例如我的本地存储路径为:C:\MySoft\assist\unrar.dll

链接:https://pan.baidu.com/s/1LiZXEaDDuekYtRqF8zFMxw  提取码:kxld

第二步 修改源码 unrarlib.py 文件

if platform.system() == \'Windows\':
    from ctypes.wintypes import HANDLE as WIN_HANDLE
    HANDLE = WIN_HANDLE
    UNRARCALLBACK = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint,
                                       ctypes.c_long, ctypes.c_long,
                                       ctypes.c_long)
    # 注释原代码
    # lib_path = lib_path or find_library("unrar.dll")
    # 将路径指向下载的动态库文件存储路径
    lib_path = r"C:\MySoft\assist\unrar.dll"
    if lib_path:
        unrarlib = ctypes.WinDLL(lib_path)

二、python文件复制

import os
import shutil


def move_or_copy_file(srcpath, dstpath, flag=\'COPY\'):
    """
    复制或剪切指定文件到指定目录
    :param srcfile: 操作的源文件路径
    :param dstfile: 操作文件目标存储路径
    :param flag: 执行的操作类型复制或剪切,默认为复制操作
    :return: 执行结果,1 为成功,0 为失败
    """

    def exec_action(srcfile, dstfile, flag=\'COPY\'):
        # 增加指定路径下的操作权限
        # os.chmod(srcfile, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
        try:
            if \'MOVE\' == flag:
                shutil.move(srcfile, dstfile)
                print("Finished moving %s -> %s" % (srcfile, dstfile))
                return 1
            else:
                shutil.copy(srcfile, dstfile)
                print("Finished copying %s -> %s" % (srcfile, dstfile))
                return 1
        except Exception as e:
            print(e)
            return 0

    result = 1
    if not os.path.exists(dstpath):
        os.makedirs(dstpath)
    if os.path.isfile(srcpath):
        result = exec_action(srcpath, dstpath, flag)
    elif os.path.isdir(srcpath):
        for root, dirs, files in os.walk(srcpath):
            for dir in dirs:
                src_dir_path = os.path.join(root, dir)
                dst_dir_path = src_dir_path.replace(srcpath, dstpath)
                if not os.path.exists(dst_dir_path):
                    os.makedirs(dst_dir_path)
            for file in files:
                if "desktop.ini" != file:
                    src_file_path = os.path.join(root, file)
                    dst_file_path = src_file_path.replace(srcpath, dstpath)
                    result = exec_action(src_file_path, dst_file_path, flag)
                    if not result:
                        return result
    else:
        print("The source file: %s does not exist" % srcpath)
        result = 0
    return result