Python-多任务复制文件夹

import multiprocessing
import os
import time


def copy_file(queue, file_name, old_folder_name, new_folder_name, count):
    """完成文件的复制"""
    # 拼凑包含完整路径的文件(夹)
    # os.path.join 把目录和文件名合成一个路径
    old_file_name = os.path.join(old_folder_name, file_name)
    new_file_name = new_folder_name + "/" + file_name
    if os.path.isdir(old_file_name):
        os.mkdir(new_folder_name + "/" + file_name)
        f_names = os.listdir(old_file_name)
        for f_name in f_names:
            copy_file(queue, f_name, old_file_name, new_file_name, count)
    # 进程池中出错,没有显示
    # print("%s复制中...." % file_name)
    else:
        old_f = open(old_file_name, 'rb')
        new_f = open(new_file_name, 'wb')
        new_f.write(old_f.read())
        old_f.close()
        new_f.close()
        count[0] += 1
        # 如果拷贝完了文件,那么就向队列中写入一个消息,表示已经完成
        queue.put(file_name)


def get_files_num(top):
    """获取文件夹及子文件夹的个数"""
    file_count = 0
    for root, dirs, files in os.walk(top, topdown=False):
        for name in files:
            file_count += 1
    return file_count


def rmdirs(top):
    for root, dirs, files in os.walk(top, topdown=False):
        # 先删除文件夹
        for name in files:
            os.remove(os.path.join(root, name))
        # 再删除空目录
        for name in dirs:
            os.rmdir(os.path.join(root, name))
    # for循环执行后top就为空目录
    # 如果要删除将下面的注释打开
    # os.rmdir(top)


def main():
    # 1 获取用户要copy的文件夹的名字
    old_folder_name = input("请输入要复制的文件夹的名字:")
    # 2 创建一个新的文件夹
    try:
        new_folder_name = old_folder_name + "[副本]"
        os.mkdir(new_folder_name)
    except:
        # os.removedirs(new_folder_name)
        # 先删除目录
        rmdirs(new_folder_name)
    # 3 获取文件夹所有的待copy的文件名字 listdir
    file_names = os.listdir(old_folder_name)
    # 4 创建进程池
    pool = multiprocessing.Pool(5)
    # 5 创建队列 显示复制的进度
    queue = multiprocessing.Manager().Queue()
    # 主进程与子进程共享这个List
    count = multiprocessing.Manager().list([0])
    # 6 向进程池中添加复制文件的任务
    for file_name in file_names:
        # 复制原文件夹中的文件, 到新文件夹中的文件去
        pool.apply_async(copy_file, args=(queue, file_name, old_folder_name, new_folder_name, count))
        # copy_file(queue, file_name, old_folder_name, new_folder_name, count)
    pool.close()
    pool.join()
    # count[0] 要等到进程结束才有值
    # 所有文件的长度
    all_file_num = get_files_num(old_folder_name)
    # 复制成功的长度
    while True:
        # file_name = queue.get()
        # print("已经完成复制: %s " % file_name)

        # print(queue.qsize())
        time.sleep(0.1)
        print("\r复制进度.. %.2f%% " % (queue.qsize() * 100 / all_file_num), end="")
        if all_file_num == queue.qsize():
            print("")
            exit()
        # if all_file_num == count[0]:
        #     print("")
        #     exit()


if __name__ == "__main__":
        main()

  这里使用两种方式来记录的进度

  第一种:使用进程之间的共享变量

 count = multiprocessing.Manager().list([0])

  第二种:使用队列的方式来记录

# 创建队列 
queue = multiprocessing.Manager().Queue()

# 获取队列的长度
queue.qsize()

# 入队列
queue.put()

  注: 显示复制的进度未完善,即使加了延时

posted @ 2019-05-25 10:16  PHPer100  阅读(306)  评论(0编辑  收藏  举报