FTP下载文件到文件夹+进度条

    任务是通过python FTP下载文件到内存 再到文件,好像没有搞清楚如何下载到内存,只是通过重载FTP中retrbinary函数,在里面增加打印下载进度条的功能,后面看到别人是拿pycurl做的,之后好好学习一下。

from ftplib import FTP
import unittest
import os
import sys


class MyFTP(FTP):#对FTP的继承  
    #重载父类中retrbinary的方法  
    def retrbinary(self, cmd, callback, fsize=0, rest=0):  
        """ 
        cmd: 命令 
        callback: 回调函数 
        fsize: 服务器中文件总大小
        rest: 已传送文件大小  
        """  
        cmpsize=rest  
        self.voidcmd('TYPE I')  
        conn = self.transfercmd(cmd, rest) #此命令实现从指定位置开始下载,以达到续传的目的  
        while 1:  
            if fsize: 
                if (fsize-cmpsize) >= 1024:
                    blocksize = 1024
                else:
                    blocksize = fsize - cmpsize
                ret=float(cmpsize)/fsize
                #print(cmpsize,fsize)
                num=ret*100
                print ('下载进度:%.2f%%'%num)  
                data = conn.recv(blocksize)  
                if not data:  
                    break  
                callback(data)  
            cmpsize+=blocksize  
        conn.close()  
        return self.voidresp()
  
    
#FTP服务器IP/用户名/密码
host = '127.0.0.1'
port = 21
username = 'li'
password = '0'

ftp=MyFTP()
ftp.connect(host,port)
ftp.login(username, password) 


def ftp_download(self, ftp, file_remote, file_local, bufsize):
    """ 
    ftp: 命令 
    file_remote: 要下载的文件名(服务器中)
    file_local: 本地文件路径
    bufsize: 服务器中文件大小 
    """  
    # 本地是否有此文件 来确认是否启用断点续传(没有这个文件)
    if not os.path.isfile(file_local):
        with open(file_local, 'wb') as f: 
            ftp.retrbinary('RETR %s' % file_remote, f.write, bufsize,0)
            f.close()

#TEST
class TestDownloader(unittest.TestCase):

    def setUp(self):
        print('setUp')


    def test_download(self):
        file_remote = '6.BMP'
        file_local = 'D:\\test_data\\'+file_remote
        #bufsize = 1024  # 设置缓冲器大小
        bufsize=ftp.size(file_remote) #服务器里的文件总大小
        ftp_download(ftp,file_remote,file_local,bufsize)
        #path=os.path
        #print(sys.argv[0])
        #print(__file__)

    def tearDown(self):
        print('tearDown')

if __name__ == '__main__':
    unittest.main()

你可能感兴趣的:(python)