我们使用 ftp 本身最重要的就是文件的传输 :上传下载
其他的都是 边缘毛毛雨,既然在上一步 我们已经做到 了登录 和遍历文件,创建文件目录,删除文件,切换目录,这次我们要做的就是 最重要的一项 就是上传和下载。
说实话 看了github上的 关于python ftp 的仓库代码 ,大部分都是 demo级别,登录完了就没有下文,偶然看到有下载上传的 ,还是不具备可参考性。自己写了些,频繁试错,坑 真是不少。
具体代码 我已经 项目化 ,可以集成给伸手党
https://github.com/mullerhai/pyFtps
先说下载
下载是使用
ftps.retrbinary('RETR fileRealname',file_handler,buffersize) 方法
首先 ftp上真实存在的文件,你要知道相对ftp服务器 文件根目录的 文件绝对路径,并可以读写它,
读写完毕要 关闭它。这里推荐使用 with 语法,不需要显式关闭它
先我们登录上
from ftplib import FTP
from ftplib import FTP_TLS
host='ftps.baidu.com'
port='21'
user='zh***ng'
pwd='zz***mt.2'
ip='117.43,135.150'
files = []
_old_makepasv = FTP_TLS.makepasv
def _new_makepasv(self):
host,port = _old_makepasv(self)
host = self.sock.getpeername()[0]
return host,port
FTP_TLS.makepasv = _new_makepasv
#实名用户 加密登录
ftps = FTP_TLS(host)
ftps.set_debuglevel(2)
ftps.auth()
ftps.login(user,pwd)
ftps.makepasv()
ftps.sendcmd('pbsz 0')
ftps.set_pasv(True)
ftps.prot_p()
下载服务器文件 代码
sever_filename='AA70p1_GDscore_20180330.txt'
local_filename='my_mac/local/path/filename.txt'
bufsize=1024 #缓冲区大小
with open(severFilename,"wb") as f:
ftps.retrbinary('RETR %s' % local_filename, f.write, bufsize)
ftps.quit #退出ftp
需要 注意的 是 retrbinary ()方法中的 'RETR' 是关键字 ,必须要有,另外 'RETR' 之后 不要带'/',
sever_filename是服务器的真实文件目录
local_filename 是你要下载到操作真实机器的本地路径,如果中间没有代理机器
local_filename 和sever_filename 可以一致, local_filename 可以只有文件名,则下载到项目里的目录中
open() 使用 ’wb' 模式, 在 ftps.retrbinary( ) 中 要使用 f.write 写。
上传 本地文件到服务器 的代码:
一
local_uploadfile='/Users/geo/Documents/pycode/xgb/geo/AA02p7_new.txt'
sever_will_savefile='AA02p7_newi.txt'
ftps.cwd("/haining/TH") #切换到要上传文件的服务器路径
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR '+ sever_will_savefile, f_up ,bufsize)
ftps.set_debuglevel(0) #关闭调试模式
ftps.quit #退出ftp
二
local_uploadfile='/Users/geo/Documents/pycode/xgb/geo/AA02p7_new.txt'
sever_will_savefile='/haining/TH/AA02p7_newi.txt'
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR '+ sever_will_savefile , f_up ,bufsize)
ftps.set_debuglevel(0) #关闭调试模式
ftps.quit #退出ftp
三
local_uploadfile='/Users/geo/Documents/pycode/xgb/geo/AA02p7_new.txt'
sever_will_savefile='AA02p7_newi.txt'
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR haining/TH/'+ sever_will_savefile, f_up ,bufsize)
ftps.set_debuglevel(0) #关闭调试模式
ftps.quit #退出ftp
以上三种都可以正常使用,另外你也可以重命名多次 一起保存
local_uploadfile='/Users/geo/Documents/pycode/xgb/geo/AA02p7_new.txt'
sever_will_savefile1='AA02p7_newi.txt'
sever_will_savefile2='AA02p7_newx.txt'
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR haining/TH/'+ sever_will_savefile1 , f_up ,bufsize)
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR haining/TH/'+ sever_will_savefile2 , f_up ,bufsize)
ftps.set_debuglevel(0) #关闭调试模式
ftps.quit #退出ftp
但是 ftps.storbinary('STOR ' ) 之后 不要单独只有 '/',否则会失败
## 这种会失败
local_uploadfile='/Users/geo/Documents/pycode/xgb/geo/AA02p7_new.txt'
sever_will_savefile='AA02p7_newi.txt'
with open(local_uploadfile,'rb') as f_up:
ftps.storbinary('STOR '+'/'+ sever_will_savefile,f_up,bufsize)
另外要注意的就是 sever_will_savefile 不要带 你自己操作电脑本地的文件路径,否则也会失败
ftps.storbinary('STOR ') 'STOR'也是 关键字 要带上,读写文件 使用 'rb'模式
需要注意的是 会有延迟 ,有时候其实是上传成功了,但是在目录中没有看到,稍等一下
文件在 项目内外 都没有关系
ftp 文件夹 单层多层也没有关系
文件上传成功后可以保证文件不会损坏丢失
目录权限是 drwxr-xr-x 就可以上传
文件 上传后需要重新命名 ,重命名的文件不可以带本地目录符号,仅仅是文件名,可以带ftp 上的文件目录路径,也可以,所以要上传到哪个目录,先切换到哪个目录
上传的目录 写明全路径,最后要以 '/'结尾,否则上传还是会失败,全路径首位 '/',可有可无,
如果是ftps.cwd('path')切换到某一路径,在
ftps.storbinary()'STOR' 后一定不要 带上 '/', 否则 会失败
file_handler ,open(), 一定要使用with open(), 否则还是容易失败。
ftps.cwd(path) ,首尾带不带'/'都可以
我们经常会碰到的错误是 在上传的时候不能创建文件,其实两种可能,一是权限不足,二是文件路径写的有问题
https://stackoverflow.com/questions/47130246/ftplib-error-perm-553-could-not-create-file-python-2-4-4?rq=1&utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
https://stackoverflow.com/questions/31613111/python-ftplib-error-553?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
https://stackoverflow.com/questions/35294662/python-ftp-method-error-553-could-not-create-file