python ftp download with progressbar

i am a new one to learn Python. Try to download by FTP. search basic code from baidu. no one tells how to show progressbar while downloading. so i try to do it myself. it works finally but need a lot parts need to be optimized.

it is like below:

ftp=FTP(IP)
ftp.login(user,pwd)

bufsize=1024
fp=open(localPath,'wb')

ftp.retrbinary('RETR '+ftpPath,fp.write,bufsize)

it works as download, but it can't show progressbar. it is very painful when you download large files. so i read the Python FTP codes and find that i can do more things in the callback function 'fp.write'

it is very helpful to get clear understand by reading the python source code. list it in the below:

def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
"""Retrieve data in binary mode. A new port is created for you.

Args:
cmd: A RETR command.
callback: A single parameter callable to be called on each
block of data read.
blocksize: The maximum number of bytes to read from the
socket at one time. [default: 8192]
rest: Passed to transfercmd(). [default: None]

Returns:
The response code.
"""
self.voidcmd('TYPE I')
conn = self.transfercmd(cmd, rest)
while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
conn.close()
return self.voidresp()

we can define a new function to get the data info.

cur=[0,] #if we use cur=0, it will report :UnboundLocalError: local variable 'cur' referenced before assignment. i don't know why too. please give me more advise.

total=ftp.size(remotePath)

def newBar(data):

    curr[0]+=len(data)

    print '%s / %s'%(curr[0],total)

    fp.write(data)

ftp.retrbinary('RETR '+ftpPath,newBar,bufsize)

 

it can print basic progress bar now. i am trying tqdm to show progressbar, will update when it works.

Good news: tqdm works now.

you can get details in the official page: https://pypi.python.org/pypi/tqdm

 the final code is like below:

from ftplib import FTP
from time import sleep
from tqdm import tqdm

def ftpConnection(IP,user,pwd):
    ftp=FTP(IP)
    ftp.login(user,pwd)
    return ftp

def downLoad(ftp,localPath,remotePath):
    # Check if the latest build in the local path, if not download it.
    if os.path.isfile(localPath):
        print time.ctime(), 'The file existed, Do not need to download again.'
        print ftp.size(remotePath)
    else:
        bufsize=1024
        fp=open(localPath,'wb')
        total=ftp.size(remotePath)
        pbar=tqdm(total=total)
        def bar(data):
            fp.write(data)
            pbar.update(len(data))
        print time.ctime(),'Begin to download: %s'%remotePath
        ftp.retrbinary('RETR '+remotePath,bar,bufsize)
        pbar.close()
        fp.close()
        print time.ctime(),'Download is finished.'

 

posted @ 2017-04-05 16:16  frostHIT  阅读(1565)  评论(0编辑  收藏  举报