返回顶部

多任务(进程)案例----- 拷贝文件夹

import multiprocessing
import os,time,random,sys

from PyQt5.Qt import  QApplication,QWidget,QFileDialog

def getDir():
    '''
    利用pyqt5 获取目录路径
    return:str
    '''
    app = QApplication(sys.argv)
    path = QFileDialog.getExistingDirectory()
    return path

def copy_file(source_dir,file_name,dest_dir):
    '''
    具体的工作函数
    :return:None
    '''
    with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest:
        text = f_source.read()
        f_dest.write(text)
    print("拷贝完成")

def main():
    #获取要复制的文件夹
    source_dir = getDir()

    #目标文件夹
    dest_dir  = source_dir +"[副本6]"

    #创建文件夹
    try:
        os.mkdir(dest_dir)
    except:
        print("文件夹已经存在")

    #获取这个文件夹中的所有普通文件名
    file_names = os.listdir(source_dir)
    # print(file_names)

    #创建进程池
    pool = multiprocessing.Pool(5)

    t1 = time.time()
    for file_name in file_names:
        pool.apply_async(copy_file,args=(source_dir,file_name,dest_dir))

    pool.close()
    pool.join()
    print("总用时:{}".format(time.time()-t1))


if __name__ == '__main__':
    main()
    '''
    测试结果
    下为进程池里进程的个数对时间的影响  (此时为 100 个文件)
    1       0.6582393646240234
    2       0.546534538269043
    3       0.5874290466308594
    5       0.6821753978729248
    10      0.6153411865234375

    下为进程池里进程的个数对时间的影响  (此时为 1000 个文件)
    1       1.9657423496246338
    2       1.3813047409057617
    3       1.304509162902832
    5       1.4211978912353516
    10      1.2317066192626953
    '''
View Code

 

改进版

加上完成进度

 1 import multiprocessing
 2 import os,time,random,sys
 3 
 4 from PyQt5.Qt import  QApplication,QWidget,QFileDialog
 5 
 6 def getDir():
 7     '''
 8     利用pyqt5 获取目录路径
 9     return:str
10     '''
11     app = QApplication(sys.argv)
12     path = QFileDialog.getExistingDirectory()
13     return path
14 
15 def copy_file(queue,source_dir,file_name,dest_dir):
16     '''
17     具体的工作函数
18     :return:None
19     '''
20     with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest:
21         text = f_source.read()
22         f_dest.write(text)
23     time.sleep(1)
24     #发送拷贝完成的文件名
25     queue.put(file_name)
26 
27 def prep_before_work():
28     '''
29     前期准备
30     return:str
31     '''
32     #获取要复制的文件夹
33     source_dir = getDir()
34 
35     #目标文件夹
36     dest_dir  = source_dir +"[副本1]"
37 
38     #创建文件夹
39     try:
40         os.mkdir(dest_dir)
41     except:
42         print("文件夹已经存在")
43 
44     #获取这个文件夹中的所有普通文件名
45     return source_dir,os.listdir(source_dir),dest_dir
46 
47 def print_rate(queue,file_names,):
48     all_file_num = len(file_names)
49     while True:
50         file_name = queue.get()
51         if file_name in file_names:
52             file_names.remove(file_name)
53         copy_rate = (all_file_num-len(file_names))*100/all_file_num
54         print("\r{:.2f}%...({})".format(copy_rate, file_name), end="")
55         if copy_rate >= 100:
56             break
57 
58 def main():
59     #前期准备,
60     source_dir,file_names,dest_dir=  prep_before_work()
61 
62     #创建进程池
63     pool = multiprocessing.Pool(5)
64 
65     #主进程和 子进程间通信 (显示进度) ---使用Queue  (不过在进程池中要使用Manager()对象的Queue())
66     queue = multiprocessing.Manager().Queue()
67 
68     for file_name in file_names:
69         pool.apply_async(copy_file,args=(queue,source_dir,file_name,dest_dir))
70     pool.close()
71     # pool.join()  #主进程 会阻塞在这, 不过此时不需要了,因为后面有循环了
72 
73     print_rate(queue,file_names)
74 
75 if __name__ == '__main__':
76     main()
View Code

 

终极版:

加上真正的进度条

import multiprocessing
import os,time,random,sys

from PyQt5.Qt import  QApplication,QWidget,QFileDialog,QProgressBar,QTimer

def getDir():
    '''
    利用pyqt5 获取目录路径
    return:str
    '''
    app = QApplication(sys.argv)
    path = QFileDialog.getExistingDirectory()
    return path

def copy_file(queue,source_dir,file_name,dest_dir):
    '''
    具体的工作函数
    :return:None
    '''
    with open(source_dir+'/'+file_name,'r') as f_source,open(dest_dir+'/'+file_name,'w') as f_dest:
        text = f_source.read()
        f_dest.write(text)
    time.sleep(1)
    #发送拷贝完成的文件名
    queue.put(file_name)

def prep_before_work():
    '''
    前期准备
    return:str
    '''
    #获取要复制的文件夹
    source_dir = getDir()

    #目标文件夹
    dest_dir  = source_dir +"[副本1]"

    #创建文件夹
    try:
        os.mkdir(dest_dir)
    except:
        print("文件夹已经存在")

    #获取这个文件夹中的所有普通文件名
    return source_dir,os.listdir(source_dir),dest_dir

def print_rate(queue,file_names):
    all_file_num = len(file_names)
    while True:
        file_name = queue.get()
        if file_name in file_names:
            file_names.remove(file_name)
        rate.value = (all_file_num-len(file_names))*100/all_file_num
        print("\r{:.2f}%...({})".format(rate.value, file_name), end="")
        if rate.value >= 100:
            break
def create_progressBar_to_show(rate):
    app  = QApplication(sys.argv)
    progressBar = QProgressBar()
    progressBar.setFixedSize(300,30)
    progressBar.setWindowTitle("进度条")

    timer = QTimer()
    def test():
        if rate.value>0:
            progressBar.show()

        progressBar.setValue(rate.value)
        if rate.value == 100:
            sys.exit(0)

    timer.timeout.connect(test)
    timer.start(100)

    sys.exit(app.exec_())

def main():
    #前期准备,
    try:
        source_dir,file_names,dest_dir =  prep_before_work()

        #创建进程池
        pool = multiprocessing.Pool(5)

        #主进程和 子进程间通信 (显示进度) ---使用Queue  (不过在进程池中要使用Manager()对象的Queue())
        queue = multiprocessing.Manager().Queue()

        for file_name in file_names:
            pool.apply_async(copy_file,args=(queue,source_dir,file_name,dest_dir))
        pool.close()
        # pool.join()  #主进程 会阻塞在这, 不过此时不需要了,因为后面有循环了

        print_rate(queue,file_names)

    except:
        print("出现异常,请检查...")



if __name__ == '__main__':
    rate = multiprocessing.Value("d",0)
    process = multiprocessing.Process(target=create_progressBar_to_show,args=(rate,))
    process.start()
    main()
View Code

 

posted @ 2019-08-28 16:47  Zcb0812  阅读(274)  评论(0编辑  收藏  举报