本帖最后由 Gin_Q 于 2020-8-10 11:13 编辑
##############
# 还没有写完
# 欢迎大佬指点
##############
# 先就这样吧 | ''' | | @ BY Cool_Breeze | | @ Rev 03 | | @ 2020/08/10 | | ''' | | | | | | | | | | import shutil | | import os | | import time | | from multiprocessing import Process,Pool,Queue,Manager | | from threading import Thread | | from concurrent.futures import ThreadPoolExecutor | | | | | | class copyf_show: | | ''' | | # 多进程复制文件 | | # 多进程复制文件加显示进度 | | # despath 目标目录 | | # soupath 源目录 | | ''' | | def __init__(self, despath, soupath): | | self.d = despath | | self.s = soupath | | self.st = os.path.dirname(soupath) | | self.q = Manager().Queue() | | self.show_d = {} | | self.count = 0 | | self.total = 0 | | if not os.path.isdir(self.d): os.mkdir(self.d) | | | | def pro_pool(self): | | ''' | | # 实时复制文件 | | # 先启动扫描目录,向管道发送数据 | | # 开启进程池,等待管道接受数据 | | # 一个进程复制一个目录层文件 | | ''' | | print('正在从 {} 复制所有文件到 {}'.format(self.s, self.d)) | | time_node = time.time() | | count = 0 | | ps = Process(target=self.scanfile) | | ps.start() | | p = Pool() | | while True: | | if self.q.empty(): continue | | t = self.q.get() | | if not t: break | | count += len(list(t.values())[0]) | | p.apply_async(self.pro_cp, (t,)) | | ps.join() | | p.close() | | p.join() | | print('总计文件数量:{}\n耗时:{} 秒'.format(count,round(time.time() - time_node, 2))) | | | | def scanfile(self): | | ''' | | # 扫描一层目录,生成字典 | | # 绝对路径为key,文件列表为值 | | # 向管道发送字典 | | ''' | | for root,dirs,files in os.walk(self.s): | | self.q.put({root:files}) | | self.q.put(False) | | | | def pro_cp(self, dif): | | ''' | | # 判断目标目录是否存在 | | # 切换路径,复制文件 | | ''' | | dpa = list(dif.keys())[0].replace(self.st, self.d) | | if not os.path.isdir(dpa): os.mkdir(dpa) | | os.chdir(dpa) | | for i,j in dif.items(): | | for nn in [os.path.join(i,k) for k in j]: | | shutil.copy(nn, dpa) | | | | def show_fun(self): | | ''' | | # 开启线程城池复制文件并打印进度条 | | ''' | | print('正在从 {} 复制所有文件到 {}'.format(self.s, self.d)) | | self.show_scanfile() | | self.count = 0 | | print('总计文件数量:{}'.format(self.total)) | | pp = Thread(target=self.show_pgr) | | pp.setDaemon(True) | | pp.start() | | for d,f in self.show_d.items(): | | self.show_pool(d, f) | | pp.join() | | | | def show_pgr(self): | | ''' | | # 进度条 | | # 已复制数除以总数乘以100 | | # 计时 | | ''' | | time_node = time.time() | | while True: | | cls = round(self.count/self.total*100) | | print('\r{:<100} {}%'.format('*'*cls, cls),end='') | | if cls == 100: | | print('\n耗时:{} 秒'.format(round((time.time() - time_node), 2))) | | break | | time.sleep(0.1) | | | | def show_scanfile(self): | | ''' | | # 扫描一层目录,生成字典 | | # 绝对路径为key,文件列表为值 | | # | | ''' | | for root,dirs,files in os.walk(self.s): | | self.total += len(files) | | self.show_d.update({root:files}) | | | | def show_pool(self, root, fl): | | ''' | | # root = 目录, fl = 文件列表 | | # 多线程 | | ''' | | dpa = root.replace(self.st, self.d) | | if not os.path.isdir(dpa): os.mkdir(dpa) | | os.chdir(dpa) | | with ThreadPoolExecutor(None, self.show_cp) as p: | | p.map(self.show_cp, [(root + os.sep + f, dpa) for f in fl]) | | p.shutdown() | | self.count += len(fl) | | | | def show_cp(self, file): | | ''' | | # 绝对路径 | | # 复制文件file = (src, dst) | | ''' | | shutil.copy(file[0], file[1]) | | | | | | if __name__ == '__main__': | | path = r'D:\GIN\py\pool_copy_file\t' | | soup = r'D:\GIN\py\photo\photo' | | t = copyf_show(path, soup) | | t.pro_pool() | | t.show_fun() | | print('Done!')COPY |
###############
测试结果: | 正在从 D:\GIN\py\photo\photo 复制所有文件到 D:\GIN\py\pool_copy_file\t | | 总计文件数量:2296 | | 耗时:2.82 秒 | | 正在从 D:\GIN\py\photo\photo 复制所有文件到 D:\GIN\py\pool_copy_file\t | | 总计文件数量:2296 | | **************************************************************************************************** 100% | | 耗时:2.91 秒 | | Done! | | | | 请按任意键继续. . .COPY |
|