背景和目的:
利用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
defge***5
(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時,直接通過ge***5方法去獲取檔案的md5值;
# 當檔案大於1m時,通過擷取整個檔案中的某幾個片段,然後拼接成乙個檔案,再去獲取其md5值,最後刪除這個檔案
defmd5
(self,path)
:if self.size <
1024
*1024
:return self.ge***5(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.ge***5(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=
# 使用requests傳送介面請求
res = self.request.send(
'post'
,'', verify=
false
, files=files)
os.remove(path1)
# 刪除存在本地的分片檔案
return res.json(
)
4.迴圈呼叫檔案上傳的介面
chunkindex =
1while chunkindex <= totalchunk:
res2 = upload.uploading(chunkindex)
chunkindex +=
1
5.從伺服器上去讀取通過介面上傳的檔案的md5值,判斷是否正確
httpclient 分片上傳檔案 檔案分片上傳
在業務場景中檔案上傳很普遍,而大檔案的上傳經常會導致上傳時長過久,大量占用頻寬資源,而分片上傳就解決了目前的問題。import react from react import from utils upload import concurrentutil from utils concurrent ...
檔案分片 檔案分片上傳原理解析
上傳大檔案時,我們一般都會採用分片上傳的方式,這樣如果上傳過程中斷了,下次繼續上傳的話就不用重新全部上傳,只需繼續上傳未上傳的部分即可,進而可以實現秒傳的效果。其原理其實就是在客戶端將檔案分割成多個小的分片,然後再將這些分片一片一片的上傳給服務端,服務端拿到所有分片後再將這些分片合併起來還原成原來的...
大檔案上傳 webuploader分片上傳
參考 webuploder api 需求 上傳大檔案資源以及一些基礎資訊儲存到資料庫 實現思路 分為2大步 一 通過webuploader前端外掛程式分頁上傳到伺服器,伺服器合頁 二 上傳完成,設定檔案欄位名稱,再普通表單提交,儲存資訊到資料庫 難點 一步具體實現 前端頁面 分頁上傳 1,匯入web...