python实现文件的多线程拷贝并使用progressbar包实现进度条
代码如下
# -*- coding: UTF-8 -*-
from __future__ import division
import threading
import time
import os
import sys
from progressbar import *
import shutil
flag=0 #用于是否拷贝成功,线程间通信使用,全局变量的方式
#复制文件的线程类
class CPFILE(threading.Thread):
def __init__(self,sour,dest): #主要传入拷贝数据的源路径和目标路径
threading.Thread.__init__(self)
self.sour=sour
self.dest=dest
def run(self):
global flag
try:
shutil.copyfile(self.sour,self.dest) #使用shutil拷贝文件
flag=2
except Exception as e:
print "文件 "+self.sour+" 拷贝失败! "+str(e)
flag=1
#print e
#进度条线程,读取目标文件大小,实时刷新进度条
class FILEPROCESS(threading.Thread):
def __init__(self,sour,dest,name): #主要传入拷贝数据的源路径和目标路径、文件名
threading.Thread.__init__(self)
self.sour=sour
self.dest=dest
self.name=name
def run(self):
global flag
x=0
y = os.stat(self.sour)[6]
#对目标大小文件进行单位换算处理
if y < 1024*1024:
file_size=str(y)+" bytes"
else:
file_size=int(y/1024/1024)
if file_size < 1024:
file_size=str(file_size)+" M"
else:
file_size=str(round(file_size/1024,2))+" G"
#widgets=[self.name+" "+file_size+" :",Percentage(), ' ', Bar('#'),' ', Timer(),' ', ETA(), ' ', FileTransferSpeed()]
#进度条显示定制 显示文件 名 文件大小 进度显示符号 使用时间 传输速度
widgets=[self.name+" "+file_size+" :",Percentage(), ' ', Bar('#'),' ', Timer(),' ', ' ', FileTransferSpeed()]
#只有传输中或成功才显示进度条
if flag == 0 or flag == 2:
pbar = ProgressBar(widgets=widgets, maxval=y).start()
while x < y:
if flag == 0 or flag == 2:
try:
x = os.stat(self.dest)[6]
pbar.update(x)
except Exception as e:
print self.dest+" 目标文件不存在"
break
#拷贝失败,则直接退出循环结束该线程
if flag==1:
break
time.sleep(0.01) #进度条更新速率
#拷贝成功才进行进度条的完成更新
if flag == 2:
pbar.finish()
#进程启动方法
def startprocerss(sou,des,name):
global flag
flag=0
threadcpfile = CPFILE(sou,des)
threadfileprocess = FILEPROCESS(sou,des,name)
threadcpfile.start()
#等待一秒钟才启动进度条的进程
time.sleep(1)
threadfileprocess.start()
#阻塞进程,完成后才进入下一个文件的拷贝
threadcpfile.join()
threadfileprocess.join()
if __name__ == '__main__':
#需要复制的文件夹
file_dir="/root/test_s"
#目标路径
file_dest="/root/test_d"
for root, dirs, files in os.walk(file_dir):
#对路径进行拆分,方便在目标路径中创建新的文件夹
fdir=root.replace(file_dir+"/","")
if fdir == file_dir:
d_dir=file_dest
else:
d_dir=file_dest+"/"+fdir
if not os.path.exists(d_dir):
try:
os.makedirs(d_dir)
except Exception as e:
print d_dir+" 文件夹创建失败! "+str(e)
for fileo in files:
source_file=root+"/"+fileo
dest_file=d_dir+"/"+fileo
startprocerss(source_file,dest_file,fileo)
程序运行情况
1、空间不足的情况
1.wmv 1.55 G :100% |#######################| Elapsed Time: 0:00:01 900.98 MB/s
2.wmv 2.97 G :100% |#######################| Elapsed Time: 0:00:04 740.12 MB/s
3.wmv 1.36 G :100% |#######################| Elapsed Time: 0:00:01 958.14 MB/s
5.wmv 21 M :100% |#########################| Elapsed Time: 0:00:00 2.14 GB/s
6.wmv 2.97 G :100% |#######################| Elapsed Time: 0:00:03 1.00 GB/s
文件 /root/test_s/7.wmv 拷贝失败! [Errno 28] No space left on device 1.25 GB/s
/root/test_d/test1 文件夹创建失败! [Errno 28] No space left on device: ‘/root/test_d/test1’
文件 /root/test_s/test1/4.wmv 拷贝失败! [Errno 2] No such file or directory: ‘/root/test_d/test1/4.wmv’
文件 /root/test_s/test1/tt.wmv 拷贝失败! [Errno 2] No such file or directory: ‘/root/test_d/test1/tt.wmv’
/root/test_d/test1/test2 文件夹创建失败! [Errno 28] No space left on device: ‘/root/test_d/test1’
文件 /root/test_s/test1/test2/file.t 拷贝失败! [Errno 2] No such file or directory: ‘/root/test_d/test1/test2/file.t’
2、正常运行
1.wmv 1.55 G :100% |#######################| Elapsed Time: 0:00:02 711.45 MB/s
2.wmv 2.97 G :100% |#######################| Elapsed Time: 0:00:04 690.87 MB/s
3.wmv 1.36 G :100% |#######################| Elapsed Time: 0:00:01 823.78 MB/s
5.wmv 21 M :100% |#########################| Elapsed Time: 0:00:00 2.02 GB/s
4.wmv 2.97 G :100% |#######################| Elapsed Time: 0:00:03 814.15 MB/s
tt.wmv 0 bytes :100% | | Elapsed Time: 0:00:00 0.00 B/s
file.t 0 bytes :100% | | Elapsed Time: 0:00:00 0.00 B/s