利用ftp服务是常见的文件服务,在项目利用也很多,现有项目使用ftp服务来下发文件来驱动测试。在以往过程中想通过多线程来提高多文件上传的效率,但是ftplib似乎不支持只建立一次连接,来实现多线程传输的过程。尝试修改成一次连接一次传输的多线程调用方式,可以实现,代码如下:
# coding=utf-8
# writre by qy.wu
import time
import threading
from ftplib import FTP
import os
def conn_ftp():
ftp = FTP()
ftp.connect(host='xx',port=21)
ftp.login(user='xxx',passwd='xxx')
return ftp
def ftp_upload(ftp,file_path):
bufsize =1204
fp = open(file_path,'rb')
remote_startname = str(file_path).split('\\')[-1]+".now"
remote_endname = str(file_path).split('\\')[-1]
ftp.storbinary('STOR '+remote_startname,fp,bufsize)
ftp.rename(remote_startname,remote_endname)
ftp.close()
class My_Th(threading.Thread):
def __init__(self,file_path):
threading.Thread.__init__(self)
self.file_path = file_path
def run(self):
myftp = conn_ftp()
ftp_upload(myftp,self.file_path)
if __name__ =="__main__":
print(time.asctime())
thread_list =[]
file_dir = []
for root,dir,files in os.walk("需要上传的文件所在目录路径"):
for i in files:
myth = My_Th(i)
thread_list.append(myth)
for i in thread_list:
i.start()
for i in thread_list:
i.join()
print(time.asctime())
以上代码在win环境下可以,linux环境下修改\\为/即可,两者目录分割符不同
以上代码中的线程数量是由list的大小决定的,当文件数据过多时肯定会出问题因此,优化代码,将启动线程数量变为可控参数。想法是将列表files均分成多个list,然后在upload方法中修改传入文件路径为传入等分后的文件路径列表。主要代码如下
##这里传入的file_path需要是文件路径列表
def ftp_upload(ftp,file_path):
bufsize = 1204
for i in file_path:
fp = open(i, 'rb')
remote_startname = str(i).split('\\')[-1] + ".now"
remote_endname = str(i).split('\\')[-1]
ftp.storbinary('STOR ' + remote_startname, fp, bufsize)
ftp.rename(remote_startname, remote_endname)
ftp.close()
相应的调用方法修改如下:
if __name__ =="__main__":
print(time.asctime())
#启动线程的数量
thread_num = 10
thread_list =[]
file_dir = []
for root,dir,files in os.walk("需要上传的文件所在目录路径"):
for i in files:
file_dir.append(i)
length = len(file_dir)
for i in range(thread_num):
do_list =file_dir[math.floor(i/thread_num*length):math.floor((i+1)/thread_num*length)]
myth = My_Th(do_list)
thread_list.append(myth)
for i in thread_list:
i.start()
for i in thread_list:
i.join()
print(time.asctime())