任务是通过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()