精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

再也不用等!Spring Boot 3.3 搞定大文件分塊上傳 + 文件“秒傳”,速度飛起!

開發 前端
通過本文,我們構建了一個完整的支持大文件上傳系統,具備高效、穩定、可擴展的特性,適用于企業級系統中的文檔上傳、視頻管理、素材收集等場景。
  • 在現代化的文件上傳場景中,用戶往往會面臨上傳大文件、網絡中斷、重復上傳浪費帶寬等挑戰。為了解決這些問題,本文基于 Spring Boot 3.3 搭建一個高性能、可擴展的文件上傳系統,支持:結合前后端完整示例,本文將帶你從零構建一套實用的上傳方案,助力各類業務系統高效接入大文件處理能力。

文件秒傳(通過 MD5 實現)

分塊上傳(支持大文件斷點續傳)

分塊合并(支持服務端合并)

構建 Spring Boot 3.3 項目

pom.xml 關鍵依賴配置如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.25</version>
    </dependency>
</dependencies>

定義文件信息實體類 FileInfo

package com.icoderoad.model;


import cn.hutool.core.util.IdUtil;


public class FileInfo {
    private String id = IdUtil.fastUUID();
    private String fileName;
    private String fileMd5;
    private Long fileSize;
    private String filePath;


    public FileInfo(String fileName, String fileMd5, Long fileSize, String filePath) {
        this.fileName = fileName;
        this.fileMd5 = fileMd5;
        this.fileSize = fileSize;
        this.filePath = filePath;
    }
}

核心服務類 FileService

package com.icoderoad.service;


import cn.hutool.crypto.digest.DigestUtil;
import com.icoderoad.model.FileInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


@Service
public class FileService {
    private final Map<String, FileInfo> fileStore = new ConcurrentHashMap<>();
    private final String tempDir = System.getProperty("java.io.tmpdir") + File.separator + "chunks";


    public FileInfo findByMd5(String md5) {
        return fileStore.get(md5);
    }


    public FileInfo saveFile(String fileName, String fileMd5, Long fileSize, String filePath) {
        FileInfo info = new FileInfo(fileName, fileMd5, fileSize, filePath);
        fileStore.put(fileMd5, info);
        return info;
    }


    public String calculateMD5(MultipartFile file) throws IOException {
        return DigestUtil.md5Hex(file.getInputStream());
    }


    public void saveChunk(MultipartFile chunk, String identifier, int index) throws IOException {
        File dir = new File(tempDir + File.separator + identifier);
        if (!dir.exists()) dir.mkdirs();
        chunk.transferTo(new File(dir, index + ".part"));
    }


    public File mergeChunks(String identifier, int totalChunks, String fileName) throws IOException {
        File dir = new File(tempDir + File.separator + identifier);
        File merged = new File(System.getProperty("java.io.tmpdir"), fileName);
        try (FileOutputStream out = new FileOutputStream(merged)) {
            for (int i = 0; i < totalChunks; i++) {
                File chunk = new File(dir, i + ".part");
                try (FileInputStream in = new FileInputStream(chunk)) {
                    byte[] buffer = new byte[1024 * 1024];
                    int len;
                    while ((len = in.read(buffer)) > 0) {
                        out.write(buffer, 0, len);
                    }
                }
            }
        }
        return merged;
    }
}

通用返回結構 Result

package com.icoderoad.common;


public class Result {
    private boolean success;
    private Object data;
    private String message;


    public Result(boolean success, Object data, String message) {
        this.success = success;
        this.data = data;
        this.message = message;
    }


    public static Result success(Object data) {
        return new Result(true, data, "成功");
    }


    public static Result error(String message) {
        return new Result(false, null, message);
    }


}

控制器 FileController

package com.icoderoad.controller;


import com.icoderoad.common.Result;
import com.icoderoad.model.FileInfo;
import com.icoderoad.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import java.io.File;


@RestController
@RequestMapping("/api/file")
public class FileController {


    @Autowired
    private FileService fileService;


    @PostMapping("/check")
    public Result check(@RequestParam("md5") String md5) {
        FileInfo exist = fileService.findByMd5(md5);
        return Result.success(exist);
    }


    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) {
        try {
            String md5 = fileService.calculateMD5(file);
            FileInfo exist = fileService.findByMd5(md5);
            if (exist != null) return Result.success(exist);
            String path = System.getProperty("java.io.tmpdir") + File.separator + file.getOriginalFilename();
            file.transferTo(new File(path));
            FileInfo saved = fileService.saveFile(file.getOriginalFilename(), md5, file.getSize(), path);
            return Result.success(saved);
        } catch (Exception e) {
            return Result.error("上傳失敗: " + e.getMessage());
        }
    }


    @PostMapping("/chunk")
    public Result uploadChunk(@RequestParam("chunk") MultipartFile chunk,
                              @RequestParam("identifier") String identifier,
                              @RequestParam("index") int index) {
        try {
            fileService.saveChunk(chunk, identifier, index);
            return Result.success("分塊上傳成功");
        } catch (Exception e) {
            return Result.error("上傳分塊失敗: " + e.getMessage());
        }
    }


    @PostMapping("/merge")
    public Result mergeChunks(@RequestParam("identifier") String identifier,
                               @RequestParam("total") int total,
                               @RequestParam("fileName") String fileName) {
        try {
            File merged = fileService.mergeChunks(identifier, total, fileName);
            String md5 = DigestUtil.md5Hex(merged);
            FileInfo info = fileService.saveFile(fileName, md5, merged.length(), merged.getAbsolutePath());
            return Result.success(info);
        } catch (Exception e) {
            return Result.error("合并失敗: " + e.getMessage());
        }
    }
}

前端: 基于 Bootstrap + SparkMD5 + Axios 實現分塊上傳與秒傳功能

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>大文件上傳 Demo</title>
<link  rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/spark-md5/spark-md5.min.js"></script>
</head>
<body class="container py-5">
<div class="card shadow-lg">
    <div class="card-header bg-primary text-white">
      <h4>大文件分塊上傳 + 秒傳 Demo</h4>
    </div>
    <div class="card-body">
      <div class="mb-3">
        <input type="file" class="form-control" id="fileInput">
      </div>
      <button class="btn btn-success" onclick="upload()">開始上傳</button>
      <div class="mt-3">
        <div class="progress">
          <div id="progressBar" class="progress-bar" role="progressbar" style="width: 0%">0%</div>
        </div>
      </div>
    </div>
</div>

<script>
    constCHUNK_SIZE=2*1024*1024;// 每塊 2MB
    let file =null;

    document.getElementById('fileInput').addEventListener('change',function(e){
      file = e.target.files[0];
    });

    asyncfunctionupload(){
      if(!file)returnalert('請選擇文件');

      const fileMD5 =awaitcalculateMD5(file);
      const chunkCount =Math.ceil(file.size/CHUNK_SIZE);

      const checkRes =await axios.get('/api/file/check',{
        params:{md5: fileMD5,fileName: file.name}
      });

      if(checkRes.data.code===200&& checkRes.data.data.exists){
        alert('服務器已存在該文件,已秒傳成功!');
        updateProgressBar(100);
        return;
      }

      for(let i =0; i < chunkCount; i++){
        const start = i *CHUNK_SIZE;
        const end =Math.min(file.size, start +CHUNK_SIZE);
        const chunk = file.slice(start, end);

        const formData =newFormData();
        formData.append('file', chunk);
        formData.append('md5', fileMD5);
        formData.append('chunk', i);
        formData.append('total', chunkCount);
        formData.append('fileName', file.name);

        await axios.post('/api/file/chunk', formData);
        updateProgressBar(Math.round(((i +1)/ chunkCount)*100));
      }

      await axios.post('/api/file/merge',null,{
        params:{md5: fileMD5,fileName: file.name}
      });

      alert('上傳并合并完成!');
    }

    asyncfunctioncalculateMD5(file){
      returnnewPromise((resolve, reject)=>{
        const chunkSize =CHUNK_SIZE;
        const chunks =Math.ceil(file.size/ chunkSize);
        let currentChunk =0;
        const spark =newSparkMD5.ArrayBuffer();
        const fileReader =newFileReader();

        fileReader.onload=e=>{
          spark.append(e.target.result);
          currentChunk++;
          if(currentChunk < chunks){
            loadNext();
          }else{
            resolve(spark.end());
          }
        };

        fileReader.onerror=()=>reject('讀取失敗');

        functionloadNext(){
          const start = currentChunk * chunkSize;
          const end =Math.min(start + chunkSize, file.size);
          fileReader.readAsArrayBuffer(file.slice(start, end));
        }

        loadNext();
      });
    }

    functionupdateProgressBar(percent){
      const bar =document.getElementById('progressBar');
      bar.style.width= percent +'%';
      bar.innerText= percent +'%';
    }
  </script>
</body>
</html>

結語

通過本文,我們構建了一個完整的支持大文件上傳系統,具備高效、穩定、可擴展的特性,適用于企業級系統中的文檔上傳、視頻管理、素材收集等場景。其核心優勢在于:

  • ?? 秒傳機制:避免重復上傳,節省資源
  • ?? 分塊傳輸:支持大文件,提升上傳穩定性
  • ?? 擴展性強:可進一步結合 Redis、MQ 等組件提升并發處理能力
責任編輯:武曉燕 來源: 路條編程
相關推薦

2020-06-15 08:03:17

大文件OOM內存

2025-07-02 00:00:00

2025-06-27 02:32:00

2021-01-15 11:40:44

文件Java秒傳

2022-08-05 08:40:37

架構

2025-07-03 07:41:34

2025-03-28 05:10:00

Spring上傳大文件

2025-10-17 07:33:14

SpringEdgeTTS語音合成

2023-11-27 17:11:02

數據庫oracle

2022-06-15 09:01:45

大文件秒傳分片上傳

2020-08-14 11:01:32

數據Pandas文件

2025-10-09 07:50:13

2021-12-21 09:05:46

命令Linux敲錯

2024-09-26 09:28:06

內存Spring

2024-04-15 00:08:00

MySQLInnoDB數據庫

2025-09-26 07:36:24

2024-11-12 09:54:23

2025-02-28 09:47:36

2015-05-29 09:01:48

2021-06-08 07:48:26

數據 Python開發
點贊
收藏

51CTO技術棧公眾號

色七七在线观看| 91在线观看网站| 久久只有这里有精品| 欧美三级精品| 亚洲男人的天堂网| 国产一区二区三区高清视频| 日韩 国产 欧美| 围产精品久久久久久久| 亚洲精美色品网站| 午夜免费福利在线| 日韩123区| 国产亚洲精品中文字幕| 92国产精品视频| 波多野结衣视频网站| 91久久久精品国产| 亚洲精品综合精品自拍| 在线播放av中文字幕| 九色porny自拍视频在线播放| 欧美激情在线一区二区三区| 成人av蜜桃| 国产精品无码一区| aa国产精品| 久久伊人免费视频| 黄色片网站免费| 成人三级av在线| 555www色欧美视频| 成年人小视频网站| av日韩国产| 成人欧美一区二区三区白人 | 国产不卡精品| 日本丶国产丶欧美色综合| www.欧美黄色| 国产区在线观看| 国产日韩欧美精品在线| 极品校花啪啪激情久久| 精品乱子伦一区二区| 蜜芽一区二区三区| 国产精品99导航| 在线观看亚洲天堂| 在线播放亚洲| 欧美肥婆姓交大片| 精品自拍偷拍视频| 久久久久久久久99精品大| 亚洲天堂av在线免费| 7788色淫网站小说| 丁香5月婷婷久久| 日韩一区二区在线看片| www.cao超碰| 日本国产亚洲| 欧美日韩一区二区在线观看 | 久久久久99精品成人片试看| 97人人精品| 色偷偷偷亚洲综合网另类 | 亚洲视频一区二区在线观看| 亚洲成人午夜在线| eeuss影院www在线观看| 久久久精品人体av艺术| 欧洲亚洲一区二区| 国产免费av在线| 国产欧美日韩一区二区三区在线观看| 欧美一级日本a级v片| 欧美老女人性开放| 久久久久久久网| 欧美深深色噜噜狠狠yyy| 四虎精品在线| 国产亚洲欧美色| 亚洲一区3d动漫同人无遮挡 | 国产精品欧美一区喷水| 亚洲一区二区在线免费观看| 欧美69xxx| 亚洲啪啪综合av一区二区三区| 日韩一二区视频| 久操av在线| 欧美性20hd另类| 欧美特级aaa| www.久久久.com| 69堂精品视频| 中文字幕视频观看| 日韩激情毛片| 中文字幕欧美国内| 国产午夜手机精彩视频| 激情久久一区| 国产97在线|亚洲| 国产精品嫩草影院桃色| 国产成人精品免费视频网站| 国产一区二区三区色淫影院| 精品三级久久久久久久电影聊斋| 国产精品不卡在线| 18禁裸男晨勃露j毛免费观看| 小早川怜子影音先锋在线观看| 91国偷自产一区二区开放时间| 超碰人人草人人| 都市激情亚洲欧美| 亚洲性日韩精品一区二区| 最新av电影网站| 99视频精品| 91精品免费看| 视频污在线观看| 国产精品国产三级国产普通话蜜臀| 天堂av在线中文| 伊人久久国产| 日韩欧美成人午夜| 国产精品一二三区在线观看| 91久久电影| 日韩美女在线观看| 国产黄色大片网站| 国产视频亚洲色图| 国产在线观看欧美| 欧美日韩视频免费看| 亚洲成人免费网站| 亚洲视频重口味| 三级亚洲高清视频| 懂色一区二区三区av片| 成人av毛片| 精品国产91久久久久久| 亚洲第一色av| 成人久久电影| 日本久久91av| 日本高清视频在线| 亚洲免费观看高清完整版在线观看| 日韩av片在线看| 99精品国产高清一区二区麻豆| 亚洲欧美日韩国产中文专区| 日韩欧美亚洲国产| 激情亚洲综合在线| 水蜜桃一区二区| 九色porny丨首页入口在线| 日韩亚洲欧美一区| 四虎地址8848| 蜜臀a∨国产成人精品| 久久精品国产一区二区三区不卡| 四虎影院观看视频在线观看| 欧美麻豆精品久久久久久| 中文字幕网站在线观看| 99在线观看免费视频精品观看| 999视频在线免费观看| 日本www在线观看| 欧美无乱码久久久免费午夜一区| 久久久久亚洲av无码专区桃色| 亚洲电影av| 国产精品久久九九| 日韩免费影院| 精品国产3级a| 国产在线免费视频| 不卡欧美aaaaa| 日本手机在线视频| 猫咪成人在线观看| 91精品国产色综合久久不卡98| 性生活免费网站| 亚洲一区影音先锋| 国内自拍偷拍视频| 国精品一区二区三区| 国产成人av一区二区三区| 亚洲综合影视| 精品三级在线看| 国产一级一片免费播放| 成人免费看的视频| 精品无码一区二区三区在线| 超碰97成人| 欧美洲成人男女午夜视频| 瑟瑟在线观看| 在线亚洲欧美专区二区| 日本理论中文字幕| 免费人成黄页网站在线一区二区| 日韩资源av在线| 四虎国产精品免费久久5151| 久久久www成人免费精品| 国产按摩一区二区三区| 亚洲午夜精品网| 一区二区三区少妇| 日本欧美久久久久免费播放网| 五月天丁香综合久久国产| 日本午夜免费一区二区| 久久99精品久久久久久青青91| 成人av一区二区三区在线观看| 亚洲不卡一区二区三区| 性欧美一区二区| 激情都市一区二区| 国产a级片网站| 奇米色欧美一区二区三区| 国产精品亚洲美女av网站| 一区二区三区伦理| 亚洲欧美国内爽妇网| 一级黄色片免费| 亚洲国产裸拍裸体视频在线观看乱了| 中国毛片在线观看| 国产专区欧美精品| 高清在线观看免费| 日韩三级在线| 国产色综合一区二区三区| 电影天堂国产精品| 色在人av网站天堂精品| 免费福利在线视频| 日韩一区二区影院| aaa在线视频| 亚洲精品老司机| 成人片黄网站色大片免费毛片| 狠狠色狠狠色综合日日91app| 男人添女荫道口图片| 日韩一区欧美| 精品国产乱码久久久久软件| 日韩电影精品| 日本久久久久久久久| av大大超碰在线| 一区二区三区在线播放欧美| 亚洲av无码国产综合专区| 欧美专区日韩专区| 日韩精品成人一区| 亚洲人成7777| 色婷婷国产精品免| 99免费精品视频| 超碰中文字幕在线观看| 视频在线在亚洲| 国产手机免费视频| 久久久9色精品国产一区二区三区| 久久精品人人做人人爽电影| 欧美午夜在线播放| 国产精品久久久精品| av免费不卡| 欧美日韩国产成人在线观看| 日本欧美在线视频免费观看| 亚洲色图25p| 无码h黄肉3d动漫在线观看| 日韩三级电影网址| 一级淫片免费看| 欧美综合亚洲图片综合区| 91看片在线播放| 亚洲在线一区二区三区| 国产稀缺精品盗摄盗拍| 中文字幕av一区二区三区免费看 | 午夜精品久久久久久久99| 欧美日韩黄色影视| 最新中文字幕免费| 日本高清免费不卡视频| 影音先锋亚洲天堂| 香蕉成人啪国产精品视频综合网 | 欧美性猛交xxxx久久久| 久久精品性爱视频| 一区二区三区精品| 精品一区在线观看视频| 最新日韩在线视频| www.com.av| 国产精品视频一二三区| 欧美激情 一区| 欧美国产欧美亚州国产日韩mv天天看完整| 国产激情在线免费观看| 久久亚洲一区二区三区四区| 欧美 变态 另类 人妖| 白白色亚洲国产精品| 亚洲啪av永久无码精品放毛片| 国产成人8x视频一区二区| 老女人性生活视频| 国产91色综合久久免费分享| 一二三区视频在线观看| 国产91富婆露脸刺激对白| 一区二区三区人妻| 粉嫩蜜臀av国产精品网站| 特黄特色免费视频| av在线这里只有精品| 精品影片一区二区入口| 久久蜜桃av一区精品变态类天堂| 成人免费看aa片| 欧美激情资源网| 国产suv精品一区二区68| 亚洲中国最大av网站| 国产成人在线播放视频| 在线视频观看一区| 国产精品久久久久久69| 欧美一级二级在线观看| 日韩中文字幕综合| 亚洲欧美日韩第一区| 欧美jizzhd欧美| 韩国日本不卡在线| 色香欲www7777综合网| 国产精品日日摸夜夜添夜夜av| 2019中文亚洲字幕| 国产精品.com| 深夜福利久久| 日韩第一页在线观看| 激情综合自拍| 亚洲成人av免费看| 国产精品资源在线| 亚洲国产综合视频| 国产精品素人一区二区| 欧美片一区二区| 欧美性xxxxx极品娇小| 91国内精品视频| 亚洲国产成人精品电影| www黄在线观看| 欧美极品少妇xxxxⅹ裸体艺术| 欧美性suv| 亚洲伊人一本大道中文字幕| 午夜a一级毛片亚洲欧洲| 综合国产精品久久久| 日韩午夜激情| 激情文学亚洲色图| 99re这里只有精品首页| 神马久久精品综合| 欧美日韩亚洲系列| a天堂在线视频| 亚洲视频电影图片偷拍一区| 手机av免费在线| 国产精品免费一区| 久久亚洲道色| 欧美日韩亚洲国产成人| 亚洲一区日本| 337p日本欧洲亚洲大胆张筱雨 | 国产在线精品免费| www.狠狠爱| 亚洲高清一区二区三区| 96亚洲精品久久久蜜桃| 亚洲精品中文字幕有码专区| 国产精品久久久久久福利| 欧美孕妇毛茸茸xxxx| 国产精品巨作av| 国产卡一卡二在线| 美女一区二区久久| caopeng视频| 五月天激情小说综合| www.香蕉视频| 久久中文字幕一区| 91国拍精品国产粉嫩亚洲一区| 国产在线一区二区三区四区| 欧美精品不卡| 国产探花在线观看视频| 国产精品免费人成网站| 亚洲中文一区二区| 国产视频亚洲视频| av剧情在线观看| 国产精品日本一区二区| 欧美人成在线| 亚洲热在线视频| 亚洲少妇屁股交4| 国产永久免费视频| 日韩性xxxx爱| 精品欧美一区二区三区在线观看| 精品国产乱码久久久久软件| 伊人久久综合| 国产污在线观看| 亚洲成a人v欧美综合天堂| 蜜桃av噜噜一区二区三区麻豆| 欧美精品在线免费播放| 欧美成人精品午夜一区二区| 日本丰满少妇黄大片在线观看| 久久精品国产免费| 情侣偷拍对白清晰饥渴难耐| 欧美视频三区在线播放| www视频在线观看免费| 国产美女精彩久久| 欧美激情成人| 午夜免费福利网站| 一区二区三区久久| 韩国av电影在线观看| 91精品国产色综合久久不卡98| 亚洲老女人视频免费| 老司机午夜av| 国产精品美日韩| 国产成人精品毛片| 欧美极品第一页| 美女久久久久| 亚洲一级免费观看| 亚洲免费在线电影| 国产 欧美 自拍| 日本国产一区二区三区| 欧美亚洲国产激情| 91欧美一区二区三区| 亚洲最大成人综合| 亚洲欧洲成人在线| 国产精品久久婷婷六月丁香| 91中文字幕精品永久在线| 欧美熟妇另类久久久久久多毛| 亚洲成人免费视| 成人好色电影| 亚洲在线视频福利| 亚洲久久一区| 内射毛片内射国产夫妻| 欧美一区二区三区精品| 成人免费观看在线观看| 日韩福利一区二区三区| 国产曰批免费观看久久久| 国产无码精品视频| 亚洲午夜精品久久久久久久久久久久| 亚洲天堂网站| 丰满少妇久久久| 亚洲国产精品国自产拍av| 亚洲黄色一级大片| 国产不卡av在线| 欧美国产高潮xxxx1819| 国产精品边吃奶边做爽| 欧美精品久久久久久久久老牛影院 | 亚洲国产天堂| 国产97在线 | 亚洲| 中文字幕一区二区三区四区不卡| 日本韩国在线观看| 国产精品日韩在线一区| 亚洲深夜激情| 放荡的美妇在线播放| 亚洲精品中文字幕av| 亚洲精品一二三**| 91视频免费版污|