本文斷點續傳文件思路:
- 前端(客戶端)需要根據固定大小對文件進行分片,請求后端(服務端)時要帶上分片序號和大小;
- 服務端創建conf文件用來記錄分塊位置,conf文件長度為總分片數,每上傳一個分塊即向conf文件中寫入一個127,那么沒上傳的位置就是默認的0,已上傳的就是Byte.MAX_VALUE 127(這步是實現斷點續傳和秒傳的核心步驟);
- 服務器按照請求數據中給的分片序號和每片分塊大小(分片大小是固定且一樣的)算出開始位置,與讀取到的文件片段數據,寫入文件。
分片上傳/斷點續傳測試驗證:
1、分片上傳

2、斷點續傳
演示步驟:
a、文件上傳一定大小,關閉瀏覽器,模擬中斷,此時上傳服務器中會有如下內容:

打開conf文件,會有如下內容:

其中小方形為已經上傳的塊號
b、瀏覽器繼續上傳同一份文件


秒傳
1、什么是秒傳
通俗的說,你把要上傳的東西上傳,服務器會先做MD5校驗,如果服務器上有一樣的東西,它就直接給你個新地址,其實你下載的都是服務器上的同一個文件,想要不秒傳,其實只要讓MD5改變,就是對文件本身做一下修改(改名字不行),例如一個文本文件,你多加幾個字,MD5就變了,就不會秒傳了。
2、本文實現的秒傳核心邏輯
a、利用redis的set方法存放文件上傳狀態,其中key為文件上傳的md5,value為是否上傳完成的標志位;
b、當標志位true為上傳已經完成,此時如果有相同文件上傳,則進入秒傳邏輯。如果標志位為false,則說明還沒上傳完成,此時需要在調用set的方法,保存塊號文件記錄的路徑,其中key為上傳文件md5加一個固定前綴,value為塊號文件記錄路徑。
3、核心代碼邏輯
private boolean setUploadProgress2Redis(FileUploadRequestDTO param, String uploadDirPath, String fileName, File confFile, byte isComplete) { RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class); if (isComplete == Byte.MAX_VALUE) { redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "true"); redisUtil.del(FileConstant.FILE_MD5_KEY + param.getMd5()); confFile.delete(); return true; } else { if (!redisUtil.hHasKey(FileConstant.FILE_UPLOAD_STATUS, param.getMd5())) { redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "false"); redisUtil.set(FileConstant.FILE_MD5_KEY + param.getMd5(), uploadDirPath + FileConstant.FILE_SEPARATORCHAR + fileName + ".conf"); } return false; } }
源碼下面會提供下載(還附帶其他SpringBoot的學習源碼,項目中稍作修改可直接使用)

