#-*- encoding: UTF8 -*-
import ftplib, string
from ftplib import FTP
import os, sys
import threading
class MyFtp:
def __init__(self, ip,user,passwd,port):
self.ip=ip
self.user=user
self.passwd=passwd
self.port=port
self.ftp=ftplib.FTP(ip,user,passwd,port)
def download_by_thread(self, filename,threadNum=1,blocksize=8196):
self.filename=filename
self.threadNum=threadNum
self.blocksize=blocksize
# 待下载的文件名称
onlyname = os.path.basename(filename)
# 取得要下载的文件的大小
cmd = "SIZE "+filename
ret = self.ftp.sendcmd(cmd)
self.ftp.quit()
#print ret
# 计算用多线程下载时,每一个线程应该下载的大小
fsize = int(string.split(ret)[1])
bsize = fsize / threadNum #每一块的大小
#print bsize
# 创建线程
threads=[]
rest = None
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)
#print threadNum-1, begin, lastsize
tp = threading.Thread(target=self.download_file, args=(threadNum-1, filename, begin,lastsize,blocksize,rest,))
threads.append(tp)
print 'threads:', len(threads)
for t in threads:
t.start()
for t in threads:
t.join()
# 每个线程都下载完成了,合并临时文件为一个文件
#print '1'
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(8196) #每次读取数据大小
if not len(data):
break
fw.write(data)#将数据写入同名文件中
f1.close()
#os.remove(fname)
fw.close()
print 'all ok'
def download_file(self, inx, filename, begin=0, size=0, blocksize=8196, rest=None):
print '%s,%s,%s,%s' %(inx,filename,begin,size)
onlyname = os.path.basename(filename)
tname = threading.currentThread().getName()
#print tname
myftp = ftplib.FTP(self.ip,self.user,self.passwd,self.port)
print '%s,%s,%s,%s' %(self.ip,self.user,self.passwd,self.port)
fp = open(onlyname+'.part.'+str(inx), 'wb')
callback = fp.write
haveread = 0
myftp.voidcmd('TYPE I')
#print myftp.voidcmd('TYPE I')
cmd1 = "REST "+str(begin)
#print tname, cmd1
ret = myftp.sendcmd(cmd1)
cmd = "RETR "+filename
conn = myftp.transfercmd(cmd, rest)
#print conn
readsize = blocksize
print '2'
while 1:
if size > 0:
last = size - haveread
if last > blocksize:
readsize = blocksize
else:
readsize = last
print readsize
data = conn.recv(readsize)
#print data
if not data:
break
if haveread > size:
print tname, 'haveread:', haveread, 'size:', size
hs = haveread - size
callback(data[:hs])
break
if 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
print ret
ftp = MyFtp('xxxxx','xxxx','xxxxx','21')
filename='/bf/check.rar'
ftp.download_by_thread(filename)
执行结果如下:
Thread-1 426 Connection closed; transfer aborted.
麻烦各位老手同学提示下什么问题,在下,在此谢过了。