分片上傳-

  • ?分片上傳原理:客戶端將選擇的文件進行切分,每一個分片都單獨發送請求到服務端;
  • 斷點續傳 & 秒傳原理:客戶端
    發送請求詢問服務端某文件的上傳狀態
    ,服務端響應該文件已上傳分片,客戶端再將未上傳分片上傳即可;
    • 如果沒有需要上傳的分片就是秒傳;
    • 如果有需要上傳的分片就是斷點續傳;
  • 每個文件要有自己唯一的標識,這個標識就是將整個文件進行MD5加密,這是一個Hash算法,將加密后的Hash值作為文件的唯一標識;
    • 使用spark-md5第三方工具庫,spark-md5是指一個用于計算MD5哈希值的前端JavaScript庫
  • 文件的合并時機:當服務端確認所有分片都發送完成后,此時會發送請求通知服務端對文件進行合并操作;

如下圖所示是前端分片上傳的整體流程:

  • 第一步:將文件進行分片,并計算其Hash值(文件的唯一標識)
  • 第二步:發送請求,詢問服務端文件的上傳狀態
  • 第三步:根據文件上傳狀態進行后續上傳
    • 文件已經上傳過了
      • 結束 --- 秒傳功能
    • 文件存在,但分片不完整
      • 將未上傳的分片進行上傳 --- 斷點續傳功能
    • 文件不存在
      • 將所有分片上傳
  • 第四步:文件分片全部上傳后,發送請求通知服務端合并文件分片

案例實現

  • 前端使用 Element Plus UI

  • 實現文件選擇 → 計算 Hash → 分片上傳 → 進度顯示

  • 假設后端提供接口

    1. POST /upload/check → 接收 fileHash,返回已上傳分片列表

    2. POST /upload/chunk → 上傳單個分片

    3. POST /upload/merge → 所有分片上傳完成后通知合并

<template><el-upload:file-list="fileList":before-upload="beforeUpload":show-file-list="false"><el-button type="primary">選擇文件上傳</el-button></el-upload><el-progressv-if="uploading":percentage="uploadProgress":text-inside="true"></el-progress>
</template><script setup>
import { ref } from 'vue';
import SparkMD5 from 'spark-md5';
import axios from 'axios';const fileList = ref([]);
const uploadProgress = ref(0);
const uploading = ref(false);
const chunkSize = 2 * 1024 * 1024; // 2MB// 計算文件Hash
function calculateFileHash(file) {return new Promise((resolve, reject) => {const spark = new SparkMD5.ArrayBuffer();const fileReader = new FileReader();const chunks = Math.ceil(file.size / chunkSize);let currentChunk = 0;fileReader.onload = e => {spark.append(e.target.result);currentChunk++;if (currentChunk < chunks) {loadNext();} else {resolve(spark.end());}};fileReader.onerror = () => reject('文件讀取錯誤');function loadNext() {const start = currentChunk * chunkSize;const end = Math.min(file.size, start + chunkSize);fileReader.readAsArrayBuffer(file.slice(start, end));}loadNext();});
}// 分片上傳
async function uploadFileChunks(file, fileHash) {const chunks = Math.ceil(file.size / chunkSize);// 先詢問服務端已上傳分片const { data } = await axios.post('/upload/check', { fileHash });const uploadedChunks = data.uploaded || [];let uploadedCount = 0;for (let i = 0; i < chunks; i++) {if (uploadedChunks.includes(i)) {uploadedCount++;uploadProgress.value = Math.floor((uploadedCount / chunks) * 100);continue; // 已上傳,跳過}const start = i * chunkSize;const end = Math.min(file.size, start + chunkSize);const chunkData = file.slice(start, end);const formData = new FormData();formData.append('file', chunkData);formData.append('fileHash', fileHash);formData.append('index', i);await axios.post('/upload/chunk', formData, {onUploadProgress: e => {// 分片進度可加權到整體進度const chunkProgress = e.loaded / e.total;uploadProgress.value = Math.floor(((uploadedCount + chunkProgress) / chunks) * 100);},});uploadedCount++;uploadProgress.value = Math.floor((uploadedCount / chunks) * 100);}// 分片上傳完成,通知合并await axios.post('/upload/merge', { fileHash, totalChunks: chunks });
}// 選擇文件上傳
async function beforeUpload(file) {uploading.value = true;uploadProgress.value = 0;fileList.value = [file];// 計算Hashconst fileHash = await calculateFileHash(file);// 分片上傳await uploadFileChunks(file, fileHash);uploading.value = false;ElMessage.success('文件上傳完成!');return false; // 阻止默認上傳
}
</script>

1.文件 Hash 的作用是什么?為什么要計算 Hash?

Hash 用作文件的唯一標識,可以判斷文件是否已經上傳過(秒傳),也可以實現斷點續傳。

同樣,合并分片后可以通過 Hash 校驗文件完整性。

2.Hash 是怎么計算的?為什么要用增量計算?

使用 FileReader 將文件分片讀取,逐塊用 SparkMD5 增量計算 Hash。

對大文件一次性計算 Hash 內存占用大且阻塞界面,增量計算避免一次性加載整個文件。

fileReader.readAsArrayBuffer異步讀取分片,觸發fileReader.onload回調添加到spark中

3.大文件上傳可能出現性能瓶頸,你如何優化?

并發上傳多分片,充分利用帶寬,提高上傳速度。

分片大小調節,避免請求次數過多或分片過大導致單次失敗。

Hash 計算優化,例如只讀取前 N MB + 文件大小組合做快速 Hash。

4.前端上傳大量分片時,瀏覽器內存會不會撐爆?如何避免?

通過分片逐塊讀取,每次只在內存中處理當前分片,讀取完成后釋放內存。

5.單個分片上傳失敗怎么處理?

前端可設置自動重試次數(如 3 次)。

若多次失敗,提示用戶網絡異常或重試。

6.分片上傳完成后如何合并?

按分片索引順序讀取所有分片,順序寫入最終文件,生成完整文件。

合并完成后再次計算文件 Hash 或 MD5,與客戶端 Hash 比對,如果一致,說明文件完整。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95734.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

零知開源——基于STM32F103RBT6的智能風扇控制系統設計與實現

?零知IDE 是一個真正屬于國人自己的開源軟件平臺&#xff0c;在開發效率上超越了Arduino平臺并且更加容易上手&#xff0c;大大降低了開發難度。零知開源在軟件方面提供了完整的學習教程和豐富示例代碼&#xff0c;讓不懂程序的工程師也能非常輕而易舉的搭建電路來創作產品&am…

ReACT Agent概述

目錄 1. 核心思想&#xff1a;解決傳統方法的局限性 2. ReACT 的工作原理&#xff1a;一個循環過程 3. 技術實現的關鍵要素 4. ReACTAgent 在任務中的具體工作流程 5. 優勢與重要性 6. 挑戰與局限性 總結 ReACT 是一個非常重要的框架&#xff0c;它代表了構建能夠推理&a…

必知!機器人的分類與應用:RPA、人形與工業機器人

每當提及“機器人”這三個字&#xff0c;許多人的第一反應或許仍是科幻電影中那種具備人類外形、可自由行走與對話的仿生裝置。然而&#xff0c;一個值得深入探討的科技現實是&#xff1a;我們對于人形機器人的迷戀&#xff0c;更多源自文化敘事與情感投射&#xff0c;而非真實…

最快的 C 語言 JSON 庫 - yyjson

文章目錄DOM 模式下的性能比對一、AWS EC2 (AMD EPYC 7R32, gcc 9.3)二、iPhone (Apple A14, clang 12)持續更新中 持續更新中 持續更新中一個用 ANSI C(C89) 編寫的高性能 JSON 庫 API.md DOM 模式下的性能比對 DOM 模式&#xff0c;即構建完整 JSON 內存結構后訪問數據的模…

TP8 模型save更新不成功

一、User文件頭部代碼class User extends Model {const TITLE_NAME 用戶;//名稱//不能刪除protected $name user_; //表名 protected $connection \app\services\database\model\DbConnModel::CONN_DB_SITE; //數據庫的連接二、更新部分我要更新user_1用戶表中的用戶信息$se…

中囯移動電視盒子(魔百和)B860AV2.1-A2和CM311-5-zg刷機手記

文章目錄B860AV2.1-A2電視盒子情況打開隱藏或屏蔽的功能進入Recovery模式打開WiFi&#xff08;如果被隱藏&#xff09;打開運維調試打開ADB調試安裝第三方應用、設置第三方桌面等&#xff08;Fiddler抓包替換官方App安裝包&#xff09;開啟ADB和使用ADB禁止“首次啟動設置”刷機…

【系統架構設計(14)】項目管理下:軟件質量與配置管理:構建可靠軟件的基礎保障

文章目錄一、核心思想二、軟件質量屬性&#xff1a;定義"好軟件"的標準三、質量保證與控制&#xff1a;實現質量標準的方法四、CMMI模型&#xff1a;組織質量能力的演進路徑五、軟件配置管理&#xff1a;質量成果的保護機制六、軟件工具&#xff1a;質量管理的技術支…

碼農的“必修課”:深度解析Rust的所有權系統(與C++內存模型對比)

在軟件開發的世界里&#xff0c;內存管理是至關重要的一個環節。它是程序運行的基礎&#xff0c;直接關系到程序的性能、穩定性和安全性。一個糟糕的內存管理策略&#xff0c;可能導致內存泄漏、野指針、緩沖區溢出等一系列令人頭疼的問題&#xff0c;甚至帶來災難性的安全漏洞…

Java全棧學習筆記30

# MySQL 卸載安裝版電腦管家/360/控制面板卸載mysql服務即可刪除ProgramData中的MySQL目錄解壓版winr 輸入 services.msc 打開服務管理。查看是否存在MySQL&#xff0c;如果存在則刪除注冊表 winR regedit 打開注冊表計算機\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Servic…

Transformers 學習入門:前置知識補漏

在學習 Transformers 之前&#xff0c;打好神經網絡和自然語言處理的基礎至關重要。本文整理了需要掌握的核心前置知識&#xff0c;用通俗的例子幫你快速理解復雜概念&#xff0c;為后續學習鋪平道路。? 一、神經網絡基礎? 1. 多層感知機&#xff08;MLP&#xff09;&#xf…

雙攝工業相機的主要特點和應用場景

雙攝工業相機&#xff08;雙目攝像頭&#xff09;在工業領域中的應用非常廣泛&#xff0c;其核心優勢在于通過雙鏡頭模擬人眼立體視覺&#xff0c;能夠獲取深度信息并實現高精度三維重建。 一、雙攝工業相機的核心優勢 深度感知與三維重建 雙目攝像頭通過兩個鏡頭從不同角度拍…

YOLOv11改進:FocalModulation替換SPPF(精度更高的空間金字塔池化)

YOLOv11&#xff1a;FocalModulation替換SPPF&#xff08;精度更高的空間金字塔池化&#xff09; 引言 在目標檢測領域&#xff0c;YOLO系列算法以其高效性和準確性廣受歡迎。作為YOLO系列的最新成員之一&#xff0c;YOLOv11在多個方面進行了優化和改進。其中&#xff0c;空間金…

LLM與數據工程的融合:衡石Data Agent的語義層與Agent框架設計

在數字經濟浪潮中&#xff0c;企業數據智能正經歷從"工具輔助"到"智能協同"的范式躍遷。傳統BI系統受限于靜態報表與預設指標&#xff0c;難以應對動態業務場景的復雜需求。衡石科技發布的HENGSHI SENSE 6.0通過"Data AI Agent"架構創新&#x…

假設一個算術表達式中包含圓括號、方括號和花括號3種類型的括號,編寫一個算法來判別,表達式中的括號是否配對,以字符“\0“作為算術表達式的結束符

思想:這道題是棧的應用類型&#xff0c;我們可以建立一個棧來保存(,[,{,通過遍歷字符串如果是三個左括號其中一個則入棧&#xff0c;當遇到)]}則出棧配對&#xff0c;如果左右匹配&#xff0c;則遍歷下一個元素&#xff0c;如果不匹配直接返回&#xff0c;如果遍歷字符串結束&a…

鴻蒙Next的UI國際化與無障礙適老化實踐:構建全球包容的數字世界

科技不應讓任何人掉隊&#xff0c;鴻蒙Next正將這一理念變為現實在全球化日益深入的今天&#xff0c;應用的國際化與無障礙設計不再是"錦上添花"&#xff0c;而是不可或缺的核心競爭力。華為鴻蒙Next系統從設計之初就深入考慮了這些需求&#xff0c;為開發者提供了完…

深度學習——遷移學習

遷移學習作為深度學習領域的一項革命性技術&#xff0c;正在重塑我們構建和部署AI模型的方式。本文將帶您深入探索遷移學習的核心原理、詳細實施步驟以及實際應用中的關鍵技巧&#xff0c;幫助您全面掌握這一強大工具。遷移學習的本質與價值遷移學習的核心思想是"站在巨人…

RAG|| LangChain || LlamaIndex || RAGflow

大模型&#xff1a;預訓練模型 外掛知識庫&#xff1a;知識庫->向量數據庫 輸入-》預處理成向量 提示詞-》llm歸納總結 離線&#xff1a;企業原文本存到向量數據庫 向量&#xff1a; 同一個向量模型&#xff08;第二代檢索&#xff0c;推薦&#xff0c;個人助理&#xff0c;…

mcp_clickhouse代碼學習

引言:當ClickHouse遇上MCP 作為一個基于Model Context Protocol(MCP)框架的ClickHouse查詢服務器,mcp_clickhouse不僅在技術實現上展現了優雅的設計思路,更在架構層面提供了許多值得借鑒的解決方案。 一、項目概覽:架構初探 mcp_clickhouse是一個專為ClickHouse數據庫設計…

前端三件套+springboot后端連通嘗試

本文承接自跨域請求問題淺解-CSDN博客 后端&#xff1a; //主啟動類 SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}} //控制類 RestController RequestMapping(&quo…

決策樹、ID3決策樹(信息熵、信息增益)

目錄 一、決策樹簡介 決策樹建立過程 二、ID3決策樹 核心思想&#xff1a;決策樹算法通過計算??信息增益??來選擇最佳分裂特征 1、信息熵 2、信息熵的計算方法 3、信息增益 4、信息增益的計算&#xff08;難點&#xff09; 5、ID3決策樹構建案例 三、總結 一、決策樹簡介 決…