PYTHON单任务FTP断点续传程序
自己寫的單任務(wù)FTP斷點續(xù)傳程序,新創(chuàng)建的任務(wù)會存到日志文件中(可存儲多個任務(wù)的日志),異常中斷重啟時可以選擇指定任務(wù)繼續(xù)下載。程序比較簡單,也可以說比較簡陋,有些問題并未細(xì)致的考慮,比如磁盤空間不足的情況。SO,僅是作為一個簡單的學(xué)習(xí)例程(給自己,也給那些認(rèn)為可以學(xué)習(xí)學(xué)習(xí)的朋友們,或許想偷懶的人還可以拿去簡單的應(yīng)用)!
?
myctrl.py#-*-encoding:gbk-*- #Author:沒車步行 #Email:lu_zhouyu@hotmail.com #Edit:2009-4-7 #Copyright:轉(zhuǎn)載請注明出處 import sys import base64 import shelve import myftplib import osshlfp='task.dat'class mytask:"""shlf:任務(wù)隊列remoteip:遠(yuǎn)程服務(wù)器IP,默認(rèn)localhostremoteport:遠(yuǎn)程服務(wù)器端口,默認(rèn)21remotepath:遠(yuǎn)程服務(wù)器路徑,默認(rèn)根目錄remotefilename:遠(yuǎn)程服務(wù)器文件,必填項localpath:本地路徑,默認(rèn)程序目錄localfilename:本地文件,默認(rèn)同遠(yuǎn)程服務(wù)器文件taskcode:任務(wù)代碼,用于判斷任務(wù)是否已存在,假設(shè)性條件無限制loginname:遠(yuǎn)程服務(wù)器登錄名loginpassword:遠(yuǎn)程服務(wù)器登錄密碼"""shlf=shelve.open(shlfp)remoteip='localhost'remoteport='21'remotepath=localpath=''localfilename=remotefilename=''taskcode=''loginname=''loginpassword=''def __init__(self):self.printtask()def maketask(self,remotefilename,localfilename,**kwargs):self.remotefilename=remotefilenameif localfilename:self.localfilename=localfilenameelse:self.localfilename=remotefilenamefor k in kwargs.keys():v=kwargs[k]if k=='remoteip' and v!='':self.remoteip=velif k=='remoteport' and v!='':self.remoteport=velif k=='remotepath' and v!='':self.remotepath=velif k=='localpath' and v!='':self.localpath=velif k=='loginname' and v!='':self.loginname=velif k=='loginpassword' and v!='':self.loginpassword=vself.starttask()def removetask(self,taskid):del self.shlf[taskid]def starttask(self):taskid='1'if len(self.shlf):taskid=str(int(max(self.shlf.keys()))+1)taskval={}taskval['remoteip']=self.remoteiptaskval['remoteport']=self.remoteporttaskval['remotepath']=self.remotepathtaskval['remotefilename']=self.remotefilenametaskval['localpath']=self.localpathtaskval['localfilename']=self.localfilenametaskval['taskcode']=self.taskcodetaskval['loginname']=self.loginnametaskval['loginpassword']=self.loginpasswordself.shlf[taskid]=taskvalmyftplib.mywork(self.remoteip,self.remoteport,self.remotepath,self.remotefilename,self.localpath,self.localfilename,self.loginname,self.loginpassword,0)del self.shlf[taskid]self.shlf.close()def restarttask(self,taskid):taskval=self.shlf[taskid]remoteip=taskval['remoteip']remoteport=taskval['remoteport']remotepath=taskval['remotepath']remotefilename=taskval['remotefilename']localpath=taskval['localpath']localfilename=taskval['localfilename']loginname=taskval['loginname']loginpassword=taskval['loginpassword']myftplib.mywork(remoteip,remoteport,remotepath,remotefilename,localpath,localfilename,loginname,loginpassword,1)del self.shlf[taskid]self.shlf.close()def printtask(self):print '%-6s|%-15s|%s'%('任務(wù)ID','服務(wù)器地址','下載文件名')print '%s'%('-'*38)for t in self.shlf.keys():v=self.shlf[t]print '%-6s|%-15s|%s'%(t,v['remoteip'],v['remotefilename'])print ''if __name__=='__main__':mytask=mytask()if len(mytask.shlf):chk=raw_input('重新啟動已存在的下載任務(wù)(Y-是/N-否):')if chk.strip().upper()=='Y':while 1:tid=raw_input('輸入任務(wù)ID:')tid=tid.strip()if mytask.shlf.has_key(tid):mytask.restarttask(tid)breakprint '輸入有誤!',sys.exit()remoteip=raw_input("遠(yuǎn)程地址(localhost):")remoteip=remoteip.strip()remoteport=raw_input("遠(yuǎn)程端口(21):")remoteport=remoteport.strip()remotepath=raw_input("遠(yuǎn)程路徑(默認(rèn)為根目錄):")remotepath=remotepath.strip()remotefilename=raw_input("遠(yuǎn)程文件名:")remotefilename=remotefilename.strip()loginname=raw_input("登錄名:")loginname=loginname.strip()loginpassword=raw_input("登錄密碼:")loginpassword=loginpassword.strip()localfilename=raw_input("本地重命名(默認(rèn)與遠(yuǎn)程文件同名):")localfilename=localfilename.strip()localpath=raw_input("本地路徑(不存在自動創(chuàng)建):")localpath=localpath.strip()mytask.maketask(remotefilename,/localfilename,/remoteip=remoteip,/remoteport=remoteport,/remotepath=remotepath,/localpath=localpath,/loginname=loginname,/loginpassword=loginpassword)
?
myftplib.py#-*-encoding:gbk-*- #Author:沒車步行 #Email:lu_zhouyu@hotmail.com #Edit:2009-4-7 #Copyright:轉(zhuǎn)載請注明出處 from ftplib import FTP import os import sysclass MyFTP(FTP):#對FTP的繼承#繼承父類中的方法,在子類中可以直接調(diào)用#重載父類中retrbinary的方法def retrbinary(self, cmd, callback, fsize=0,rest=0):blocksize=1024cmpsize=restself.voidcmd('TYPE I')conn = self.transfercmd(cmd, rest)#此命令實現(xiàn)從指定位置開始下載,以達(dá)到續(xù)傳的目的while 1:if fsize:print '/b'*30,'下載進(jìn)度:%.2f%%'%(float(cmpsize)/fsize*100),data = conn.recv(blocksize)if not data:breakcallback(data)cmpsize+=blocksizeconn.close()return self.voidresp()def ConnectFTP(remoteip,remoteport,loginname,loginpassword):ftp=MyFTP()try:ftp.connect(remoteip,remoteport)except:return (0,'connect failed!')else:try:ftp.login(loginname,loginpassword)except:return (0,'login failed!')else:return (1,ftp)def mywork(remoteip,remoteport,remotepath,remotefilename,localpath,localfilename,loginname,loginpassword,reloadflag):res=ConnectFTP(remoteip,remoteport,loginname,loginpassword)if res[0]!=1:print res[1]sys.exit()ftp=res[1]ftp.set_pasv(0) #到這一部出現(xiàn)連接超時請償試設(shè)置非0值if remotepath:#如果文件不在FTP根目錄,則需要指定下一級目錄ftp.cwd(remotepath)fsize=ftp.size(remotefilename)#獲取遠(yuǎn)程文件大小print '目標(biāo)文件大小:',fsizeif fsize==0:returnlocalfullpath=localfilenameif localpath:localfullpath=localpath+'/'+localfilenameif not os.path.exists(localpath):os.makedirs(localpath)if reloadflag and os.path.isfile(localfullpath):rest=os.stat(localfullpath).st_size#獲取本地文件的大小if rest:if rest==fsize:print '遠(yuǎn)程文件大小與本地文件大小相同,刪除任務(wù)!'returnprint '/b'*30,'已經(jīng)下載:%.2f%%'%(float(rest)/fsize*100),raw_input('回車?yán)^續(xù)....')ftp.retrbinary('RETR '+remotefilename,open(localfullpath,'ab').write,fsize,rest)else:ftp.retrbinary('RETR '+remotefilename,open(localfullpath,'wb').write,fsize)print '完成文件大小:',os.stat(localfullpath).st_size
?
轉(zhuǎn)載請注明出處?
總結(jié)
以上是生活随笔為你收集整理的PYTHON单任务FTP断点续传程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实战 Mantle 解析界面app 科技
- 下一篇: Indy相关函数用法