這一篇博客是繼上一篇博客,想了解的可以直走右拐。
上一篇主要講了客戶端的界面,這一篇主要講解FTP客戶端的兩個功能,文件下載,以及壓縮下載。
文件下載
調(diào)用處
self.downbt = Button(self.right, text='下載', command=self.download)
定義download函數(shù)
def download(self):
self.getrootpath()
check = self.list.get(self.list.curselection())
self.dpath = []
self.downloadfiles(check, self.rootpath)
self.f.cwd('/'.join(self.path))
- self.getrootpath來獲取下載的存放路徑,具體獲取代碼如下:
def getrootpath(self):
self.rootpath = os.path.join(os.path.curdir, 'download')
if not os.path.exists(self.rootpath):
os.mkdir(self.rootpath)
直接在當(dāng)前目錄下創(chuàng)建download文件夾,用來存放下載的文件。
- check = self.list.get(self.list.curselection())用來獲取選中的目錄或文件。
- self.dpath用來存儲下載的目錄的深度,主要為了下載的時候能夠準(zhǔn)確定位當(dāng)前下載的準(zhǔn)確位置
- self.downloadfiles(check, self.rootpath),具體的下載代碼
def downloadfiles(self,dirs,rootpath):
if dirs:
try:
self.f.cwd(dirs)
self.dpath.append(dirs)
newdir = os.path.join(rootpath,'/'.join(self.dpath))
if not os.path.exists(newdir):
os.mkdir(newdir)
for dir in self.f.nlst():
self.downloadfiles(dir,rootpath)
self.dpath.pop()
nowpath = '/'.join(self.path)+'/'+'/'.join(self.dpath)
self.f.cwd(nowpath)
except ftplib.error_perm:
newfile = os.path.join(rootpath,'/'.join(self.dpath)+'/'+dirs)
with open(newfile,'wb') as f:
self.f.retrbinary('RETR %s' % (dirs), f.write)
下載代碼也是很簡單,進(jìn)入到該目錄(cwd),這個時候如果是文件夾,就不會發(fā)生異常,如果不是文件夾,那么就可以認(rèn)定是文件了
i. 先假定是文件夾,那么記錄目錄深度(self.dpath.append(dirs)),并在本地創(chuàng)建目錄,然后遞歸調(diào)用下載代碼,遍歷該目錄下的所有文件。這一層文件遍歷完了之后,更新目錄深度(self.dpath.pop()),這個時候需要ftp也要同時更新其所在目錄,self.path在上一個博客已經(jīng)說明,其代表用戶進(jìn)入目錄,這里可以看做是用戶最后一次點(diǎn)擊進(jìn)行下載的那個目錄,加上下載的目錄深度,也就是當(dāng)前的目錄了,舉個例子
1. 用戶在‘home/user’點(diǎn)擊,那么我們的self.path記錄的是['home','user']
2. 然后下載‘name/name1’中的文件,當(dāng)前的dirs也就是name1,
這個時候我們的self.dpath記錄的是['name','name1']
3. 當(dāng)遍歷完name1下的文件之后,我們需要pop self.dpath頂部的路徑,
這個時候self.dpath存儲的就是['name']
4. 最后我們所處的路徑就是'home/user/name',也就是self.path和self.dpath的連結(jié)。
ii. 如果是文件的話,那么就會被異常捕獲,這個時候只需要通過retrbinary,將ftp的文件以二進(jìn)制的形式寫入到本地即可。
5.遠(yuǎn)程跳轉(zhuǎn)到選擇的文件位置即可
壓縮下載
調(diào)用處
self.ziplist = Button(self.right, text='備份', command=self.zipdownload)
定義zipdownload函數(shù)
def zipdownload(self):
self.getrootpath()
check = self.list.get(self.list.curselection())
rootpath = os.path.join(self.rootpath, 'temp')
if not os.path.exists(rootpath):
os.mkdir(rootpath)
self.dpath = []
self.downloadfiles(check, rootpath)
zipname = os.listdir(rootpath)[0]
temppath = os.path.join(rootpath, zipname)
z = zipfile.ZipFile(os.path.join(self.rootpath, zipname + '.zip'), 'w', zipfile.ZIP_DEFLATED)
for dirpath, dirnames, filenames in os.walk(temppath):
for file in filenames:
z.write(os.path.join(dirpath, file))
z.close()
self.rmtemp(rootpath)
self.f.cwd('/'.join(self.path))
- 創(chuàng)建temp文件夾用來臨時存放下載文件
- zipname = os.listdir(rootpath)[0] 獲取下載文件夾的名字,后面壓縮的文件名即這個名字
- 創(chuàng)建壓縮包,通過zipfile.ZipFile進(jìn)行創(chuàng)建,然后遍歷temp中的文件,os.walk會找到目錄下的所有文件,將每個文件寫入到壓縮文件中即可
- 刪除temp臨時目錄
def rmtemp(self,temppath):
for root, dirs, files in os.walk(temppath, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(temppath)
通過os.walk遍歷temp臨時文件夾,files中存放的是文件,dirs存放的是文件夾,先刪除文件,可以避免刪除文件夾失敗,最后刪除該臨時文件夾,就完成了刪除。
5.遠(yuǎn)程跳轉(zhuǎn)到選擇的文件位置即可
上述過程是否看懂了呢,F(xiàn)TP客戶端就先到這里了。