使用进程池和队列,完成文件夹拷贝案例

代码

# 使用进程池和队列,完成文件夹拷贝案例
# 在脚本同级目录下有个test文件夹, 里面只放了许多文本文件, 没有第二级目录


# 多进程
import multiprocessing
import os


def copy_file(file_name, source_folder, target_folder, queue):
    """
    完成拷贝任务
    :param file_name: 需要拷贝的文件名
    :param source_folder: 源文件夹
    :param target_folder: 目标文件夹
    :param queue: 队列, 拷贝完成时往队列中存放文件名
    :return: None
    """
    try:
        # 1.打开源文件
        source_file = open(source_folder + "/" + file_name, "rb")
        # 2. 打开目标文件
        target_file = open(target_folder + "/" + file_name, "wb")
        while True:
            # 3.读取源文件数据
            source_data = source_file.read(1024)

            # 当读取到文件末尾, 没有数据时, 退出循环
            if len(source_data) == 0:
                break
            # 4.往目标文件写数据
            target_file.write(source_data)
        # 5.关闭文件
        source_file.close()
        target_file.close()

    except Exception as error:
        print(error)

    # 6.往队列中放进已经复制好的文件名
    queue.put(file_name)


def main():
    # 1.获取用户要拷贝文件夹的名字
    source_folder = input("请输入要拷贝文件夹的名字:")
    # 2.获取这个文件夹里的文件列表
    source_file_list = os.listdir(source_folder)

    # 3.创建一个新的文件夹
    # 目标目录
    target_folder = source_folder + "[复件]"
    # 如果不存在目标文件夹, 就创建
    if not os.path.isdir(target_folder):
        # 创建文件夹
        os.mkdir(target_folder)

    # 4.创建进程池, 池中最多2个进程
    process_pool = multiprocessing.Pool(2)
    # 5.创建一个进程池中使用的队列
    queue = multiprocessing.Manager().Queue()
    # 6. 根据文件列表, 循环往进程池中添加需要复制的任务
    for file_name in source_file_list:
        # 往进程池中添加需要复制的任务
        # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
        process_pool.apply_async(copy_file, (file_name, source_folder, target_folder, queue))
    # 关闭进程池, 关闭后, 不再接收新的任务
    process_pool.close()
    # 完成复制的文件列表
    done_file_list = list()
    # 7.主进程中通过队列获取拷贝进度
    while True:
        # 从队列中获取 完成拷贝的文件名
        done_filename = queue.get()
        # 完成的任务添加到 完成复制的文件列表
        done_file_list.append(done_filename)
        # 进度, 完成的任务数 除以 总的任务数
        speed_of_progress = len(done_file_list) / len(source_file_list)
        # 进度在一行上刷新
        print("\r当前的拷贝的总进度为{}% ".format(speed_of_progress * 100), end="")
        # 当全部拷贝任务完成时, 退出循环
        if speed_of_progress >= 1:
            break
    print()
    # 等待进程池中的任务执行完成
    process_pool.join()


if __name__ == '__main__':
    main()

运行效果

在这里插入图片描述

拷贝结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值