Vue.Js及Java實現(xiàn)文件分片上傳代碼實例
說明
代碼從項目中剝離修改,未經(jīng)測試,僅提供思路。
前端
upload(file) {
//從后臺獲取已經(jīng)上傳的文件分片數(shù)
getIdx(md5)
.then(function(res) {
let retry = 3;
uploadPart(retry, file, res.data);
})
.catch();
}
uploadPart(retry, file, idx) {
//設置分片大小(單位Byte)
let bufferLength = 1024 * 1024 * 5;
//計算開始的切割點,idx是上傳成功的分片數(shù),未上傳過文件則開始點為0
let start = idx * bufferLength;
//全部上傳完畢或重試次數(shù)用完則退出
if(start>=file.size || retry<=0) return;
//計算分割的位置
let end = start + bufferLength;
//如果分割點超出文件大小,回退分割點
if (end > file.size) {end = fileSize;}
//切割文件
var chunk = file.slice(start, end);
//創(chuàng)建 formData 對象并添加數(shù)據(jù)
let formData = new FormData();
formData.set("file", chunk);
//如果是第一次上傳,連同文件塊數(shù)量也上傳
if (start == 0) {
//計算文件切片總數(shù),向上取整
let chunkNum = Math.ceil(file.size / bufferLength);
formData.set("total", chunkNum);
}
//上傳文件的api,此處使用axios發(fā)送請求
doUpload(formData)
//發(fā)送成功,則上傳下一片,遞歸調(diào)用方法
.then(function() {
retry = xx;//刷新重試次數(shù)
uploadPart(retry, file, ++idx);
})
//發(fā)送失敗
.catch(function() {
retry--;//重試次數(shù)減一
//重試上傳這一片
uploadPart(retry, file, idx);
});
},
文件分片上傳的前端關鍵代碼只有一句:
//切割文件
var chunk = file.slice(start, end);
通過slice方法來切割文件,然后文件上傳的流程視業(yè)務和具體技術而定,此處是使用axios發(fā)送請求,用遞歸調(diào)用上傳文件塊。
需要注意的是,Blob.slice(start, end),文件塊包含start指向的字節(jié),而不包含end指向的字節(jié),在使用時要注意Blob的邊界。
mozilla對slice的說明
后端
/**合并文件的實際操作*/
public static void doMergeFiles(String outFile, String[] files) {
//設置緩存大小
int BUFSIZE = 1024 * 1024;
//排序。文件后綴名是文件的順序。
Arrays.sort(files);
//輸出流
FileChannel outChannel = null;
//標記最后的一個文件
String lastFlag = files[files.length-1];
try {
outChannel = new FileOutputStream(outFile).getChannel();
//遍歷文件列表
for(String f : files){
//最后一塊文件用真實大小設置緩存,避免自動填充數(shù)據(jù)造成的md5不一致
if(lastFlag.equals(f)){
File last = new File(f);
BUFSIZE = (int) last.length();//獲取文件的大小并設置成緩存的大小
}
FileChannel fc = new FileInputStream(f).getChannel();
//用ByteBuffer創(chuàng)建緩存
ByteBuffer bb = ByteBuffer.allocate(BUFSIZE);
while(fc.read(bb) != -1){//把數(shù)據(jù)讀到緩存
bb.flip();//重置游標
outChannel.write(bb);//寫入數(shù)據(jù)
bb.clear();//清空數(shù)據(jù)
}
fc.close();//關閉流
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {if (outChannel != null) {outChannel.close();}} catch (IOException ignore) {}
}
}
后端的關鍵是合并文件,當上傳完最后一塊文件就進行文件的合并。使用ByteBuffer緩存,使用FileChannel進行文件的讀寫完成合并操作。在保存文件時,文件名取一致,文件的后綴名則取文件塊的順序,比如第一塊文件是“xxx.01”,第10塊是“xxx.10”,注意,個位數(shù)前面要補“0”,這樣可以直接用Array.sort()進行排序。
為提高性能,可以適當設置緩存大小,可以邊上傳文件邊合并,不必等到文件都上傳了才合并。
拓展
此處的文件上傳是一次上傳一片,上傳成功才開始上傳下一片。如果前端不是使用javascript,能開啟使用多線程的話,可以改成同時上傳多片文件提高上傳速度。已經(jīng)上傳的文件分片用bitmap存儲,上傳文件前,從后臺獲取已上傳的文件分片的bitmap數(shù)據(jù)然后解析,多線程處理未上傳的文件分片。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Vue2.0結(jié)合webuploader實現(xiàn)文件分片上傳功能
- vue實現(xiàn)大文件分片上傳與斷點續(xù)傳到七牛云
- 使用Vue3+ElementPlus前端實現(xiàn)分片上傳的全過程
- 利用Vue3+Element-plus實現(xiàn)大文件分片上傳組件
- vue大文件分片上傳之simple-uploader.js的使用
- Java實現(xiàn)大文件的分片上傳與下載(springboot+vue3)
- vue3+element 分片上傳與分片下載功能實現(xiàn)方法詳解
- Vue3利用組合式函數(shù)和Shared Worker實現(xiàn)后臺分片上傳
- vue分片上傳視頻并轉(zhuǎn)換為m3u8文件播放的實現(xiàn)示例
相關文章
教你如何將Springboot項目成功部署到linux服務器
這篇文章主要介紹了如何將Springboot項目成功部署到linux服務器上,本文分步驟給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
Spring Cloud Consul實現(xiàn)選舉機制的代碼工程
Spring Cloud Consul 是 Spring Cloud 提供的對 HashiCorp Consul 的支持,它是一種基于服務網(wǎng)格的工具,用于實現(xiàn)服務注冊、發(fā)現(xiàn)、配置管理和健康檢查,本文給大家介紹了如何用Spring Cloud Consul實現(xiàn)選舉機制,需要的朋友可以參考下2024-11-11
Springboot下使用Redis管道(pipeline)進行批量操作
本文主要介紹了Spring?boot?下使用Redis管道(pipeline)進行批量操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05
springboot運行jar生成的日志到指定文件進行管理方式
這篇文章主要介紹了springboot運行jar生成的日志到指定文件進行管理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04

