马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 Cool_Breeze 于 2020-8-10 11:28 编辑
##############
# 还没有写完
# 欢迎大佬指点
##############
# 先就这样吧
'''
@ BY Cool_Breeze
@ Rev 03
@ 2020/08/10
'''
#coding=utf-8
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 = {} #show
self.count = 0 #show
self.total = 0 #show
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!')
###############
测试结果:正在从 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!
请按任意键继续. . .
|