📄 threadftp.py
字号:
#coding=gb2312
import ftplib,string
import os,sys
import threading
class MyFTP:
def __init__(self,host='',user='',passwd=''):
self.host=host
self.user=user
self.passwd=passwd
self.filename=''
self.ftp=ftplib.FTP(host,user,passwd)
def download_by_thread(self,filename,threadnum=1,blocksize=8192):
self.filename=filename
#获取文件名
onlyname=os.path.basename(filename)
cmd="SIZE "+filename
#取得下载文件的大小
ret=self.ftp.sendcmd(cmd)
self.ftp.quit()
#计算多线程下载时,每一个线程应下载的大小
fsize=int(string.split(ret)[1])
print 'file',filename,'size:',fsize
rest=None
modsize=fsize % threadnum
print modsize
if modsize==0:
bsize=fsize/threadnum
else:
bsize=fsize/(threadnum-1)
#创建线程
threads=[]
for i in range(0,threadnum-1):
begin=bsize*i
print i,begin,bsize
tp=threading.Thread(target=self.download_file,args=(i,
filename
,begin
,bsize
,blocksize
,rest,))
threads.append(tp)
have1=bsize*threadnum
have2=fsize-have1
lastsize=bsize+have2
begin=bsize*(threadnum-1)
tp=threading.Thread(target=self.download_file,args=(threadnum-1,
filename
,begin
,bsize
,blocksize
,rest,))
threads.append(tp)
print 'threads:',len(threads)
for t in threads:
t.start()
for t in threads:
t.join()
#每个线程下载完以后,合并为一个文件
fw=open(onlyname,'wb')
for i in range(0,threadnum):
fname=onlyname+'.part.'+str(i)
print fname
if not os.path.isfile(fname):
print 'not found',fname
continue
f1=open(fname,'rb')
while 1:
data=f1.read(8192)
if not len(data):
break
fw.write(data)
f1.close()
os.remove(fname)
fw.close()
print '下载完毕'
def download_file(self,inx,filename,begin=0,size=0,blocksize=8192,rest=None):
onlyname=os.path.basename(filename)
tname=threading.currentThread().getName()
#新建一个连接来下载,每个线程一个连接,注意这里没有考虑ftp服务器限制一个ip练多少问题
myftp=ftplib.FTP(self.host,self.user,self.passwd)
#创建临时文件
fp=open(onlyname+'.part.'+str(inx),'wb')
callback=fp.write
haveread=0
myftp.voidcmd('TYPE I')
#告诉服务器要从文件那个位置下载
cmd1='REST '+str(begin)
print tname,cmd1
ret=myftp.sendcmd(cmd1)
#开始下载
cmd='RETR '+filename
conn=myftp.transfercmd(cmd,rest)
readsize=blocksize
while 1:
if size>0:
last=size-haveread
if last>blocksize:
readsize=blocksize
else:
readsize=last
data=conn.recv(readsize)
if not data:
break
#已经下载数据长度
haveread=haveread+len(data)
#只能下载指定长度的数据,下载到就退出
if haveread>size:
print tname,'haveread:',haveread,'size:',size
hs=haveread-size
callback(data[:hs])
break
elif haveread==size:
callback(data)
print tname,'haveread:',haveread
break
callback(data)
conn.close()
fp.close()
try:
ret=myftp.getresp()
except Exception,e:
print tname,e
myftp.quit()
return ret
ftp=MyFTP('192.168.0.118','anonymous','')
filename='/软件/delphi/Delphi7.iso'
ftp.download_by_thread(filename,10)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -