精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

97精品超碰一区二区三区| 久久久久久久久久久妇女| 欧美日韩亚洲一区二区| 欧美尤物一区| 国产白浆在线观看| 国产视频亚洲| 中文字幕亚洲国产| 成年人小视频在线观看| 唐人社导航福利精品| 成人免费在线视频观看| 国产原创精品| 91黄色在线视频| 一本久道久久综合狠狠爱| 在线精品视频视频中文字幕| 日韩欧美色视频| 欧美美女日韩| 亚洲主播在线观看| 亚洲 国产 日韩 综合一区| 99久久精品国产一区色| 久久久国产精品一区二区中文| zzjj国产精品一区二区| 国内精品久久99人妻无码| 在线免费成人| 在线观看日韩国产| 国产曰肥老太婆无遮挡| 黄网站视频在线观看| 91久色porny| 91免费版网站在线观看| 日本妇乱大交xxxxx| 亚洲麻豆一区| 欧美超级乱淫片喷水| 一区二区三区四区免费| 亚洲精品一区在线| 欧美猛男gaygay网站| 久久午夜夜伦鲁鲁一区二区| 老牛影视精品| 亚洲综合区在线| 三年中文高清在线观看第6集 | 欧美人与禽性xxxxx杂性| 国产精品情趣视频| 欧美日韩在线高清| 四季av日韩精品一区| 粉嫩av一区二区三区| 91性高湖久久久久久久久_久久99| 免费无码国产精品| 99精品视频免费全部在线| 欧美精品九九久久| 特级片在线观看| 在线精品视频在线观看高清| 日韩在线观看av| 日本激情视频一区二区三区| 日韩成人激情| 色妞久久福利网| 天堂网av2018| 久久在线视频| zzijzzij亚洲日本成熟少妇| 人人澡人人澡人人看| 97久久视频| 日韩资源在线观看| 欧美三级黄色大片| 综合久久亚洲| 久久久久久国产精品三级玉女聊斋| 青青草原国产视频| 亚洲激情女人| 欧美亚洲在线视频| 天天干,天天干| 奇米影视一区二区三区小说| 国产深夜精品福利| 91精品国产色综合久久不8| 紧缚奴在线一区二区三区| 国产日韩在线一区| 国产成人毛毛毛片| 99精品在线观看视频| 免费久久99精品国产自| 搞黄视频在线观看| 中文字幕亚洲一区二区va在线| 青青草原网站在线观看| 免费av不卡在线观看| 精品久久久中文| 成人精品小视频| 91成人小视频| 亚洲成色999久久网站| 亚洲综合网在线观看| av资源久久| 一区二区三区精品99久久| 国产老头老太做爰视频| 在线不卡欧美| 国产精品福利网站| 成人黄色免费视频| 国产亚洲自拍一区| 在线观看成人免费| 少妇视频在线观看| 91麻豆精品国产91久久久资源速度 | 欧美手机在线观看| 在线日韩视频| 国产精品一区二区电影| 成人免费公开视频| 国产欧美精品一区aⅴ影院 | 亚洲一区电影在线观看| 尹人成人综合网| 国产精品日韩专区| 日韩一区免费视频| 中文字幕中文字幕在线一区 | 1区2区在线| 欧美日韩一区视频| av电影中文字幕| 亚洲欧美激情四射在线日| 色视频www在线播放国产成人| 女同久久另类69精品国产| 欧美亚韩一区| 国产精品久久久999| 亚洲va天堂va欧美ⅴa在线| 久久久电影一区二区三区| 久久免费一级片| 亚洲天堂1区| 亚洲精品ady| 欧美激情图片小说| 日韩激情一区二区| 精品国产一区二区三区免费| 日本高清在线观看wwwww色| 午夜精品福利一区二区三区av | 日韩黄色影院| 日本久久精品电影| 第四色在线视频| 欧美一区二区三区免费看| 国产精品高精视频免费| 婷婷丁香花五月天| 一区二区三区在线免费视频| 亚洲一级片免费| 欧美女优在线视频| 51精品国产黑色丝袜高跟鞋| 成人黄色在线观看视频| 亚洲三级电影全部在线观看高清| 女性隐私黄www网站视频| 欧美a一欧美| 韩国美女主播一区| 亚洲第一色网站| 亚洲三级免费观看| 污色网站在线观看| 日韩av自拍| 国产精品一区二区三| 9色在线观看| 欧美三级电影在线看| 欧美人妻一区二区三区| 欧美亚洲专区| 欧美日韩三区四区| 黑人巨大精品| 一级做a爰片久久毛片美女图片| 久久精品无码av| 久久久99精品免费观看| 青青艹视频在线| 色吊丝一区二区| 日韩免费黄色av| 成年人视频在线看| 欧美日韩一卡二卡三卡| 一级免费黄色录像| 国产精品影音先锋| 台湾无码一区二区| 久久精品论坛| 欧美有码在线视频| 国产高清免费av在线| 欧美三级在线看| 国产suv一区二区三区| 成人一区二区三区中文字幕| 九一国产精品视频| 欧美人与物videos另类xxxxx| 国产不卡av在线免费观看| jyzzz在线观看视频| 欧美高清一级片在线| 青青草在线观看视频| 99久久久久久| 国产91色在线观看| 中文一区一区三区免费在线观看| av成人综合网| 性孕妇free特大另类| 在线色欧美三级视频| 97人妻精品一区二区三区软件 | 中文字幕亚洲色图| 国产又黄又大又粗的视频| 亚洲综合丝袜美腿| 91网站免费入口| 精品亚洲成av人在线观看| 日本wwwcom| 视频一区在线观看| 91九色单男在线观看| www.51av欧美视频| 永久555www成人免费| 99热这里只有精品66| 精品二区三区线观看| 国产91丝袜美女在线播放| 国产精品亚洲成人| 国产成人精品无码播放| 午夜久久福利| 日本成人看片网址| 日韩国产在线不卡视频| 热re91久久精品国99热蜜臀| 男人在线资源站| 日韩精品极品在线观看| 97视频免费在线| 狠狠躁夜夜躁人人爽天天天天97| 99久久久免费精品| 97成人超碰视| 少妇性l交大片7724com| 久久久夜夜夜| 91午夜在线观看| 日韩在线高清| 欧美国产视频在线观看| 欧美激情精品| 国产精品久久久久9999| 成人超碰在线| 久久亚洲精品一区二区| 你懂的在线观看视频网站| 日韩欧美综合在线| 6—12呦国产精品| 一本久久a久久免费精品不卡| 欧美成人片在线观看| 国产精品嫩草99a| 中文精品在线观看| 成人免费三级在线| 国产亚洲色婷婷久久| 免费看欧美女人艹b| 精品人妻一区二区三区四区在线| 午夜精品剧场| 日本道在线视频| 99精品在线观看| 色999五月色| 亚洲v天堂v手机在线| 亚洲aⅴ日韩av电影在线观看 | 深爱五月激情网| 成人国产在线观看| 18禁一区二区三区| 国产一区二区精品久久99| 小泽玛利亚视频在线观看| 久久精品主播| 少妇高潮喷水久久久久久久久久| 亚洲视频综合| 又大又硬又爽免费视频| 国内视频精品| 日本一区午夜艳熟免费| 黄色综合网站| 91免费黄视频| 国产欧美日本| 亚洲熟妇无码另类久久久| 黄色日韩在线| 国产人妻777人伦精品hd| 亚洲激情国产| 人妻熟女一二三区夜夜爱| 在线亚洲成人| 久久精品香蕉视频| 三级不卡在线观看| 黄色av免费在线播放| 日欧美一区二区| 9久久婷婷国产综合精品性色 | 免费在线中文字幕| 欧美黑人又粗大| 日本不卡免费高清视频在线| 91精品国产高清久久久久久| 亚洲精品日产| 国产精品成人免费视频| 开心久久婷婷综合中文字幕| 成人久久精品视频| 涩爱av色老久久精品偷偷鲁| 国产精品久久国产精品| 日韩中文av| 亚洲一区二区精品在线观看| 91精品亚洲| 青草视频在线观看视频| 久久高清免费观看| 三级av免费观看| 国产成人精品综合在线观看 | 日韩极品一区| 免费极品av一视觉盛宴| 99精品视频免费观看| 免费国产成人av| 国产精品正在播放| 女人被狂躁c到高潮| 国产精品美女一区二区三区| 加勒比婷婷色综合久久| 精品久久久久久久中文字幕| 亚洲图片小说视频| 精品剧情v国产在线观看在线| 天堂资源中文在线| 久久精品欧美视频| 黄色在线观看www| 国产精品视频色| 国产色噜噜噜91在线精品| 日韩欧美精品在线不卡| 亚洲精品中文字幕乱码| 欧美亚洲国产成人| 激情五月婷婷综合| 欧美做受喷浆在线观看| 中文字幕一区二区三中文字幕| 久久精品一级片| 在线免费观看日本欧美| 亚洲国产精品一| 有码中文亚洲精品| 97人人爽人人澡人人精品| 国产精品女主播| 久久综合另类图片小说| 一区二区精品免费视频| 国产女优一区| 一区二区在线免费观看视频| 国产日韩三级在线| 日韩精品国产一区二区| 51精品秘密在线观看| 青青草免费在线视频| 欧美乱妇40p| a屁视频一区二区三区四区| 国产一区二区三区色淫影院| 91精品国产自产拍在线观看蜜| 无码无遮挡又大又爽又黄的视频| 国产成人精品一区二区三区四区 | 午夜精品婷婷| 日韩av在线中文| 国产欧美一二三区| 毛片视频网站在线观看| 日韩女优av电影在线观看| 尤物网在线观看| 日本一区二区三区四区视频| 国产成人在线中文字幕| 300部国产真实乱| 久久精品国产第一区二区三区| 加勒比综合在线| 欧美性猛交xxxx免费看漫画| 后入内射欧美99二区视频| 欧美成aaa人片免费看| 成人自拍视频| 亚洲视频sss| 蜜臀av性久久久久蜜臀aⅴ | 日韩精品1区| 成人在线观看黄| 久久精品夜色噜噜亚洲a∨| 日韩视频免费观看高清| 欧美大片顶级少妇| 中文字幕在线三区| 亚洲一区二区三区视频| 午夜免费一区| 日本在线观看视频一区| 国产精品免费视频一区| 国产又色又爽又黄又免费| 日韩视频永久免费观看| 亚洲视频自拍| 波多野结衣激情| 国产一区二区三区四| 久久高清内射无套| 日韩精品一区二区三区视频播放 | h视频在线免费| 国产精品女主播| 亚洲不卡av不卡一区二区| 肉色超薄丝袜脚交| 亚洲激情五月婷婷| 欧美熟女一区二区| 97人人做人人爱| 免费欧美一区| 天天色综合天天色| 综合电影一区二区三区| 国产成人精品一区二区无码呦| 久久69精品久久久久久国产越南| 中文字幕一区二区三区中文字幕| 国产中文字幕乱人伦在线观看| 成年人网站91| 亚洲欧美一二三区| 日韩在线视频播放| 久久丁香四色| 91成人在线观看喷潮教学| 久久伊人中文字幕| 亚洲视频一区二区三区四区| 麻豆国产精品va在线观看不卡 | jk漫画禁漫成人入口| 日本一区二区免费看| 久久99久久久久久久久久久| 久久一二三四区| 日韩精品视频免费在线观看| 欧美日韩国产网站| 日本一道在线观看| 91免费观看国产| 一级特黄特色的免费大片视频| 欧美成在线视频| 亚洲日产av中文字幕| 色免费在线视频| 亚洲国产精品麻豆| 国产在线自天天| 97se亚洲综合在线| 亚洲一区二区成人| 可以免费看av的网址| 亚洲精品xxx| 四虎在线精品| 日韩久久一级片| 亚洲丝袜制服诱惑| 免费av网站观看| 国产欧美一区二区三区久久| 影音先锋久久| 欧美美女性生活视频| 亚洲国产精品视频在线观看| 老司机精品视频网| 中文字幕日本最新乱码视频| 亚洲欧美一区二区三区极速播放 | 国产欧美三级电影| 老司机午夜性大片| 一本在线高清不卡dvd|