python實現檔案分片上傳的介面自動化
阿新 • • 發佈:2020-11-20
背景和目的:
利用python request 編寫指令碼測試公司系統的檔案上傳介面。前端讀取檔案的大小然後檔案分片傳給後端,後端將每一片資料重新組合成檔案。大概的過程是:前端將整個檔案的md5、size(大小)、name(檔名)、ext(檔案字尾)、totalchunk(分片總數)與分片檔案的md5、chunk(分片資料),chunkindex(當前分片檔案的下標)等傳給後臺,後臺取得這些資料後,通過chunkindex將每一片資料重組,重組完後,進行md5校驗,判斷檔案上傳是否成功。我只需要去呼叫後臺的介面,然後判斷檔案是否上傳成功,並且上傳沒有錯誤,其他的檔案校驗就不用去深究。
開發前端使用的是vue,後臺使用的是php,要利用python實現對這一介面的呼叫,那麼就先要將前端資料給模擬出來,然後迴圈去呼叫介面,將檔案分片上傳,我的思路大概如下:
1.獲取整個檔案的大小、名字、字尾、分片總數,定義每片檔案的大小:
def __init__(self,data): dat = json.loads(data) self.path = dat['path'] # 獲取檔案路徑 self.CHUNK_SIZE = 1024*1024*2 # 定義每片檔案的大小 self.size = os.path.getsize(dat['path']) # 獲取檔案的大小 self.totalchunk = math.ceil(self.size / self.CHUNK_SIZE) # 獲取檔案的分片總數 self.ext = os.path.basename(dat['path']).split('.').pop() # 獲取檔案的字尾 self.name = os.path.basename(dat['path']) # 獲取檔案的名字
2.獲取檔案的md5,查看了開發那邊的md5演算法,利用python實現過程如下:
# 使用hashlib庫的md5方法獲取指定檔案的md5 def getmd5(self,path): m = hashlib.md5() with open(path,'rb') as f: for line in f: m.update(line) md5code = m.hexdigest() return md5code # 開發那邊對md5的演算法進行了優化,當檔案的大小小於1M時,直接通過getmd5方法去獲取檔案的md5值; # 當檔案大於1M時,通過擷取整個檔案中的某幾個片段,然後拼接成一個檔案,再去獲取其md5值,最後刪除這個檔案 def md5(self,path): if self.size < 1024 * 1024: return self.getmd5(path) f = open(path,'rb') f.seek(0,0) data = f.read(2012) f.seek(int(self.size / 2) - 1999,0) data += f.read(1999) f.seek(-2010,2) data += f.read(2010) f.close() path = 'D:/copy_' + str(os.path.basename(path)) f = open(path,'wb') f.write(data) f.close() val = self.getmd5(path) os.remove(path) return val
3.呼叫檔案上傳的介面
def uploading(self,chunkIndex): MD5 = self.md5(self.path) # 整個檔案的md5 start = (chunkIndex - 1) * self.CHUNK_SIZE # 擷取檔案的起始位置 end = min(self.size,start + self.CHUNK_SIZE)# 擷取檔案的結束位置 f = open(self.path,'rb') f.seek(start) data = f.read(end) # 待分片上傳的資料 f.close() path1 = 'D:/copy_' + str(os.path.basename(self.path)) # 將該資料儲存在本地 f = open(path1,'wb') f.write(data) f.close() chunk_md5 = self.md5(path1) # 讀取分片上傳資料的md5 # 將所有的資料儲存在files字典當中,利用requests的files傳輸資料 # 使用requests files型別時,要像下面一樣構建引數,不然會有錯誤 files={ 'chunk':('blob',data,'application/octet-stream'),'name':(None,self.name),'ext':(None,self.ext),'index':(None,chunkIndex),'total': (None,self.totalchunk),'size': (None,self.size),'chunk_md5': (None,chunk_md5),'md5': (None,MD5),} # 使用requests傳送介面請求 res = self.request.send('post','https://10.104.17.222/bank/elements/uploading',verify=False,files=files) os.remove(path1) # 刪除存在本地的分片檔案 return res.json()
4.迴圈呼叫檔案上傳的介面
chunkIndex = 1 while chunkIndex <= totalchunk: res2 = upload.uploading(chunkIndex) chunkIndex += 1
5.從伺服器上去讀取通過介面上傳的檔案的md5值,判斷是否正確
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。