⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threadftp.py

📁 用python编写的ftp多线程下载源码。
💻 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 + -