[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] python3 多进程复制文件,多线程复制文件加显示进度条(持续更新)Rev03

本帖最后由 Gin_Q 于 2020-8-10 11:13 编辑

##############
# 还没有写完
# 欢迎大佬指点
##############


# 先就这样吧
  1. '''
  2. @ BY Cool_Breeze
  3. @ Rev 03
  4. @ 2020/08/10
  5. '''
  6. #coding=utf-8
  7. import shutil
  8. import os
  9. import time
  10. from multiprocessing import Process,Pool,Queue,Manager
  11. from threading import Thread
  12. from concurrent.futures import ThreadPoolExecutor
  13. class copyf_show:
  14.     '''
  15.     # 多进程复制文件
  16.     # 多进程复制文件加显示进度
  17.     # despath 目标目录
  18.     # soupath 源目录
  19.     '''
  20.     def __init__(self, despath, soupath):
  21.         self.d = despath
  22.         self.s = soupath
  23.         self.st = os.path.dirname(soupath)
  24.         self.q = Manager().Queue()
  25.         self.show_d = {} #show
  26.         self.count = 0 #show
  27.         self.total = 0 #show
  28.         if not os.path.isdir(self.d): os.mkdir(self.d)
  29.     def pro_pool(self):
  30.         '''
  31.         # 实时复制文件
  32.         # 先启动扫描目录,向管道发送数据
  33.         # 开启进程池,等待管道接受数据
  34.         # 一个进程复制一个目录层文件
  35.         '''
  36.         print('正在从 {} 复制所有文件到 {}'.format(self.s, self.d))
  37.         time_node = time.time()
  38.         count = 0
  39.         ps = Process(target=self.scanfile)
  40.         ps.start()
  41.         p = Pool() #进程数量
  42.         while True:
  43.             if self.q.empty(): continue
  44.             t = self.q.get()
  45.             if not t: break
  46.             count += len(list(t.values())[0])
  47.             p.apply_async(self.pro_cp, (t,))
  48.         ps.join()
  49.         p.close()
  50.         p.join()
  51.         print('总计文件数量:{}\n耗时:{} 秒'.format(count,round(time.time() - time_node, 2)))
  52.     def scanfile(self):
  53.         '''
  54.         # 扫描一层目录,生成字典
  55.         # 绝对路径为key,文件列表为值
  56.         # 向管道发送字典
  57.         '''
  58.         for root,dirs,files in os.walk(self.s):
  59.             self.q.put({root:files})
  60.         self.q.put(False)
  61.     def pro_cp(self, dif):
  62.         '''
  63.         # 判断目标目录是否存在
  64.         # 切换路径,复制文件
  65.         '''
  66.         dpa = list(dif.keys())[0].replace(self.st, self.d)
  67.         if not os.path.isdir(dpa): os.mkdir(dpa)
  68.         os.chdir(dpa)
  69.         for i,j in dif.items():
  70.             for nn in [os.path.join(i,k) for k in j]:
  71.                 shutil.copy(nn, dpa)
  72.         
  73.     def show_fun(self):
  74.         '''
  75.         # 开启线程城池复制文件并打印进度条
  76.         '''
  77.         print('正在从 {} 复制所有文件到 {}'.format(self.s, self.d))
  78.         self.show_scanfile()
  79.         self.count = 0
  80.         print('总计文件数量:{}'.format(self.total))
  81.         pp = Thread(target=self.show_pgr)
  82.         pp.setDaemon(True)# 主程序退出结束
  83.         pp.start()
  84.         for d,f in self.show_d.items():
  85.             self.show_pool(d, f)
  86.         pp.join()
  87.     def show_pgr(self):
  88.         '''
  89.         # 进度条
  90.         # 已复制数除以总数乘以100
  91.         # 计时
  92.         '''
  93.         time_node = time.time()
  94.         while True:
  95.             cls = round(self.count/self.total*100)
  96.             print('\r{:<100} {}%'.format('*'*cls, cls),end='')
  97.             if cls == 100:
  98.                 print('\n耗时:{} 秒'.format(round((time.time() - time_node), 2)))
  99.                 break
  100.             time.sleep(0.1)
  101.     def show_scanfile(self):
  102.         '''
  103.         # 扫描一层目录,生成字典
  104.         # 绝对路径为key,文件列表为值
  105.         #
  106.         '''
  107.         for root,dirs,files in os.walk(self.s):
  108.             self.total += len(files)
  109.             self.show_d.update({root:files})
  110.     def show_pool(self, root, fl):
  111.         '''
  112.         # root = 目录, fl = 文件列表
  113.         # 多线程
  114.         '''
  115.         dpa = root.replace(self.st, self.d)
  116.         if not os.path.isdir(dpa): os.mkdir(dpa)
  117.         os.chdir(dpa)
  118.         with ThreadPoolExecutor(None, self.show_cp) as p:
  119.             p.map(self.show_cp, [(root + os.sep + f, dpa) for f in fl])
  120.         p.shutdown()
  121.         self.count += len(fl)
  122.     def show_cp(self, file):
  123.         '''
  124.         # 绝对路径
  125.         # 复制文件file = (src, dst)
  126.         '''
  127.         shutil.copy(file[0], file[1])
  128. if __name__ == '__main__':
  129.     path = r'D:\GIN\py\pool_copy_file\t'
  130.     soup = r'D:\GIN\py\photo\photo'
  131.     t = copyf_show(path, soup)
  132.     t.pro_pool()
  133.     t.show_fun()
  134.     print('Done!')
复制代码
###############
测试结果:
  1. 正在从 D:\GIN\py\photo\photo 复制所有文件到 D:\GIN\py\pool_copy_file\t
  2. 总计文件数量:2296
  3. 耗时:2.82 秒
  4. 正在从 D:\GIN\py\photo\photo 复制所有文件到 D:\GIN\py\pool_copy_file\t
  5. 总计文件数量:2296
  6. **************************************************************************************************** 100%
  7. 耗时:2.91 秒
  8. Done!
  9. 请按任意键继续. . .
复制代码

  1. 正在从 C:\user\穿越火线 复制所有文件到 D:\腾讯游戏
  2. 总计文件数量:14372
  3. **************************************************************************************************** 100%
  4. 耗时:239.89 秒
  5. 正在从 C:\user\英雄联盟 复制所有文件到 D:\腾讯游戏
  6. 总计文件数量:39048
  7. ***************                                                                                      15%
复制代码

TOP

哟西原来有这个想法的人不止我一个

TOP

返回列表