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

SpringBoot 實戰:文件上傳之秒傳、斷點續傳、分片上傳

開發 前端
在日常開發中,文件上傳的場景多種多樣。比如,在線教育平臺上的視頻資源上傳,社交平臺上的圖片分享,以及企業內部的知識文檔管理等。

文件上傳功能幾乎是每個 Web 應用不可或缺的一部分。無論是個人博客中的圖片上傳,還是企業級應用中的文檔管理,文件上傳都扮演著至關重要的角色。今天,松哥和大家來聊聊文件上傳中的幾個高級玩法——秒傳、斷點續傳和分片上傳。

一 文件上傳的常見場景

在日常開發中,文件上傳的場景多種多樣。比如,在線教育平臺上的視頻資源上傳,社交平臺上的圖片分享,以及企業內部的知識文檔管理等。這些場景對文件上傳的要求也各不相同,有的追求速度,有的注重穩定性,還有的需要考慮文件大小和安全性。因此,針對不同需求,我們有了秒傳、斷點續傳和分片上傳等解決方案。

二 秒傳、斷點上傳與分片上傳

秒傳

秒傳,顧名思義,就是幾乎瞬間完成文件上傳的過程。其實現原理是通過計算文件的哈希值(如 MD5 或 SHA-1),然后將這個唯一的標識符發送給服務器。如果服務器上已經存在相同的文件,則直接返回成功信息,避免了重復上傳。這種方式不僅節省了帶寬,也大大提高了用戶體驗。

斷點續傳

斷點續傳是指在網絡不穩定或者用戶主動中斷上傳后,能夠從上次中斷的地方繼續上傳,而不需要重新開始整個過程。這對于大文件上傳尤為重要,因為它可以有效防止因網絡問題導致的上傳失敗,同時也能節約用戶的流量和時間。

分片上傳

分片上傳則是將一個大文件分割成多個小塊分別上傳,最后再由服務器合并成完整的文件。這種做法的好處是可以并行處理多個小文件,提高上傳效率;同時,如果某一部分上傳失敗,只需要重傳這一部分,不影響其他部分。

三 秒傳實戰

后端實現

在 SpringBoot 項目中,我們可以使用 MessageDigest 類來計算文件的 MD5 值,然后檢查數據庫中是否存在該文件。

@RestController
@RequestMapping("/file")
public class FileController {
    @Autowired
    FileService fileService;

    @PostMapping("/upload1")
    public ResponseEntity<String> secondUpload(@RequestParam(value = "file",required = false) MultipartFile file,@RequestParam(required = false,value = "md5") String md5) {
        try {
            // 檢查數據庫中是否已存在該文件
            if (fileService.existsByMd5(md5)) {
                return ResponseEntity.ok("文件已存在");
            }
            // 保存文件到服務器
            file.transferTo(new File("/path/to/save/" + file.getOriginalFilename()));
            // 保存文件信息到數據庫
            fileService.save(new FileInfo(file.getOriginalFilename(), DigestUtils.md5DigestAsHex(file.getInputStream())));
            return ResponseEntity.ok("上傳成功");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("上傳失敗");
        }
    }
}

前端調用

前端可以通過 JavaScript 的 FileReader API 讀取文件內容,通過 spark-md5 計算 MD5 值,然后發送給后端進行校驗。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>秒傳</title>
    <script src="spark-md5.js"></script>
</head>
<body>
<input type="file" id="fileInput" />
<button onclick="startUpload()">開始上傳</button>
<hr>
<script>
    async function startUpload() {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        if (!file) {
            alert("請選擇文件");
            return;
        }

        const md5 = await calculateMd5(file);
        const formData = new FormData();
        formData.append('md5', md5);

        const response = await fetch('/file/upload1', {
            method: 'POST',
            body: formData
        });

        const result = await response.text();
        if (response.ok) {
            if (result != "文件已存在") {
                // 開始上傳文件
            }
        } else {
            console.error("上傳失敗: " + result);
        }
    }

    function calculateMd5(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onloadend = () => {
                const spark = new SparkMD5.ArrayBuffer();
                spark.append(reader.result);
                resolve(spark.end());
            };
            reader.onerror = () => reject(reader.error);
            reader.readAsArrayBuffer(file);
        });
    }
</script>
</body>
</html>

前端分為兩個步驟:

  1. 計算文件的 MD5 值,計算之后發送給服務端確定文件是否存在。
  2. 如果文件已經存在,則不需要繼續上傳文件;如果文件不存在,則開始上傳文件,上傳文件和 MD5 校驗請求類似,上面的案例代碼中我就沒有重復演示了,松哥在書里和之前的課程里都多次講過文件上傳,這里不再啰嗦。

四 分片上傳實戰

分片上傳關鍵是在前端對文件切片,比如一個 10MB 的文件切為 10 份,每份 1MB。每次上傳的時候,需要多一個參數記錄當前上傳的文件切片的起始位置。

比如一個 10MB 的文件,切為 10 份,每份 1MB,那么:

  • 第 0 片,從 0 開始,一共是 1024*1024 個字節。
  • 第 1 片,從 1024*1024 開始,一共是 1024*1024 個字節。
  • 第 2 片...

把這個搞懂,后面的代碼就好理解了。

后端實現

private static final String UPLOAD_DIR = System.getProperty("user.home") + "/uploads/";
/**
 * 上傳文件到指定位置
 *
 * @param file 上傳的文件
 * @param start 文件開始上傳的位置
 * @return ResponseEntity<String> 上傳結果
 */
@PostMapping("/upload2")
public ResponseEntity<String> resumeUpload(@RequestParam("file") MultipartFile file, @RequestParam("start") long start,@RequestParam("fileName") String fileName) {
    try {
        File directory = new File(UPLOAD_DIR);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        File targetFile = new File(UPLOAD_DIR + fileName);
        RandomAccessFile randomAccessFile = new RandomAccessFile(targetFile, "rw");
        FileChannel channel = randomAccessFile.getChannel();
        channel.position(start);
        channel.transferFrom(file.getResource().readableChannel(), start, file.getSize());
        channel.close();
        randomAccessFile.close();
        return ResponseEntity.ok("上傳成功");
    } catch (Exception e) {
        System.out.println("上傳失敗: "+e.getMessage());
        return ResponseEntity.status(500).body("上傳失敗");
    }
}

后端每次處理的時候,需要先設置文件的起始位置。

前端調用

前端需要將文件切分成多個小塊,然后依次上傳。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分片示例</title>
</head>
<body>
    <input type="file" id="fileInput" />
    <button onclick="startUpload()">開始上傳</button>

    <script>
        async function startUpload() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];
            if (!file) {
                alert("請選擇文件");
                return;
            }

            const filename = file.name;
            let start = 0;

            uploadFile(file, start);
        }

        async function uploadFile(file, start) {
            const chunkSize = 1024 * 1024; // 每個分片1MB
            const total = Math.ceil(file.size / chunkSize);

            for (let i = 0; i < total; i++) {
                const chunkStart = start + i * chunkSize;
                const chunkEnd = Math.min(chunkStart + chunkSize, file.size);
                const chunk = file.slice(chunkStart, chunkEnd);

                const formData = new FormData();
                formData.append('file', chunk);
                formData.append('start', chunkStart);
                formData.append('fileName', file.name);

                const response = await fetch('/file/upload2', {
                    method: 'POST',
                    body: formData
                });

                const result = await response.text();
                if (response.ok) {
                    console.log(`分片 ${i + 1}/${total} 上傳成功`);
                } else {
                    console.error(`分片 ${i + 1}/${total} 上傳失敗: ${result}`);
                    break;
                }
            }
        }
    </script>
</body>
</html>

五 斷點續傳實戰

斷點續傳的技術原理類似于分片上傳。

當文件已經上傳了一部分之后,斷了需要重新開始上傳。

那么我們的思路是這樣的:

  1. 前端先發送一個請求,檢查要上傳的文件在服務端是否已經存在,如果存在,目前大小是多少。
  2. 前端根據已經存在的大小,繼續上傳文件即可。

后端案例

先來看后端檢查的接口,如下:

@GetMapping("/check")
public ResponseEntity<Long> checkFile(@RequestParam("filename") String filename) {
    File file = new File(UPLOAD_DIR + filename);
    if (file.exists()) {
        return ResponseEntity.ok(file.length());
    } else {
        return ResponseEntity.ok(0L);
    }
}

如果文件存在,則返回已經存在的文件大小。

如果文件不存在,則返回 0,表示前端從頭開始上傳該文件。

前端調用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>斷點續傳示例</title>
</head>
<body>
<input type="file" id="fileInput"/>
<button onclick="startUpload()">開始上傳</button>

<script>
    async function startUpload() {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        if (!file) {
            alert("請選擇文件");
            return;
        }

        const filename = file.name;
        let start = await checkFile(filename);

        uploadFile(file, start);
    }

    async function checkFile(filename) {
        const response = await fetch(`/file/check?filename=${filename}`);
        const start = await response.json();
        return start;
    }

    async function uploadFile(file, start) {
        const chunkSize = 1024 * 1024; // 每個分片1MB
        const total = Math.ceil((file.size - start) / chunkSize);

        for (let i = 0; i < total; i++) {
            const chunkStart = start + i * chunkSize;
            const chunkEnd = Math.min(chunkStart + chunkSize, file.size);
            const chunk = file.slice(chunkStart, chunkEnd);

            const formData = new FormData();
            formData.append('file', chunk);
            formData.append('start', chunkStart);
            formData.append('fileName', file.name);

            const response = await fetch('/file/upload2', {
                method: 'POST',
                body: formData
            });

            const result = await response.text();
            if (response.ok) {
                console.log(`分片 ${i + 1}/${total} 上傳成功`);
            } else {
                console.error(`分片 ${i + 1}/${total} 上傳失敗: ${result}`);
                break;
            }
        }
    }
</script>
</body>
</html>

這個案例實際上是一個斷點續傳+分片上傳的案例,相關知識點并不難,小伙伴們可以自行體會下。

六 總結

好了,以上就是關于文件上傳中秒傳、斷點續傳和分片上傳的實戰分享。通過這些技術的應用,我們可以極大地提升文件上傳的效率和穩定性,改善用戶體驗。希望各位小伙伴在自己的項目中也能靈活運用這些技巧,解決實際問題。


責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2021-01-15 11:40:44

文件Java秒傳

2022-06-15 09:01:45

大文件秒傳分片上傳

2025-10-29 04:15:00

OSS分片CDN

2025-07-03 07:41:34

2017-08-08 08:45:44

前端文件斷點續傳

2023-06-20 19:57:13

2011-03-04 16:41:57

FileZilla

2020-04-02 20:07:17

前端vuenote.js

2023-03-09 12:04:38

Spring文件校驗

2021-01-18 05:19:11

數字指紋

2022-08-05 08:40:37

架構

2013-07-22 14:02:17

iOS開發ASIHTTPRequ

2009-08-28 15:38:49

C#實現斷點續傳

2024-07-02 10:18:18

2025-07-02 00:00:00

2025-06-27 02:32:00

2017-12-20 15:11:48

iOS緩存文件斷點機制

2025-06-17 08:39:43

2011-03-01 14:12:12

FreebsdProftpd

2009-11-16 10:49:43

PHP上傳文件代碼
點贊
收藏

51CTO技術棧公眾號

欧美第一精品| 欧美精品总汇| 91麻豆国产福利在线观看| 欧美一级淫片播放口| 免费网站在线高清观看| 国产精品高潮久久| 日韩毛片视频在线看| 国产精品手机在线| 亚洲免费视频二区| 欧美日韩亚洲一区| 亚洲欧美国产视频| 亚洲av毛片在线观看| 三级在线观看视频| 亚洲欧美一区二区三区孕妇| 国内精品久久国产| 91精品国产乱码久久久| 欧美日韩免费| 亚洲精品影视在线观看| 91网址在线观看精品| 这里有精品可以观看| 国产精品区一区二区三区| 国产精品加勒比| 日韩精品在线一区二区三区| 亚洲午夜黄色| 日韩午夜在线视频| 182在线视频| 欧美日韩卡一| 欧美视频在线观看免费网址| 国产精品国三级国产av| 国产小视频免费在线网址| 国产成人在线免费| 国产精品稀缺呦系列在线| 国产午夜精品一区二区理论影院| 日韩欧美大片| 日韩精品亚洲元码| 免费看91视频| 日韩一区二区三免费高清在线观看| 五月天激情小说综合| 中国黄色录像片| 91青青在线视频| 久久综合久久鬼色中文字| 99re6在线| 99riav国产| 毛片基地黄久久久久久天堂| 国产成人中文字幕| 精产国品一区二区| 性欧美长视频| 91精品国产高清自在线看超| 九九免费精品视频| 欧美精品18| 久久精品99久久久久久久久| www亚洲色图| 国产欧美日韩一区二区三区四区 | www.com欧美| 狠狠久久亚洲欧美| 成人乱人伦精品视频在线观看| 天天爱天天做天天爽| 国产毛片一区| 国产91精品青草社区| 国产午夜性春猛交ⅹxxx| 中文日韩欧美| 欧美最猛性xxxxx亚洲精品| 久久久久久91亚洲精品中文字幕| 亚洲人成免费| 91成人在线观看国产| 久久黄色精品视频| 日韩二区三区在线观看| 国产精品久久久久免费a∨大胸| 黄色av一区二区| 日本中文字幕不卡| 国产一区二区在线播放| 91麻豆视频在线观看| 韩国成人福利片在线播放| 91久久爱成人| 日韩在线观看视频一区二区三区| 99精品视频在线观看| 久久99导航| 九色视频在线播放| 国产精品久久久爽爽爽麻豆色哟哟 | xfplay精品久久| 日本欧美精品久久久| 一级毛片视频在线| 亚洲欧美另类久久久精品2019| 警花观音坐莲激情销魂小说| 丰乳肥臀在线| 色呦呦国产精品| theporn国产精品| 中文字幕日韩高清在线| 日韩成人av网址| 摸摸摸bbb毛毛毛片| 亚洲网色网站| 4444欧美成人kkkk| 国产一区二区三区黄片| 成人av免费网站| 欧美亚洲丝袜| av在线网址观看| 3d动漫精品啪啪一区二区竹菊| 久久久久久久久电影| 国产精彩视频在线| 免费日韩av| 成人免费高清完整版在线观看| 亚洲av无码乱码国产麻豆| 久久久午夜精品| 亚洲欧美激情插 | 美女精品一区最新中文字幕一区二区三区 | 日本一区视频在线| 一区二区三区视频在线观看视频| 一区二区三区**美女毛片| 女性隐私黄www网站视频| 日韩大陆av| 日韩成人av在线| 午夜精品一区二区三区视频| 亚洲一区国产| 92福利视频午夜1000合集在线观看| 四虎永久在线精品免费网址| 国产精品无人区| 欧美一区二区中文字幕| 亚洲一区有码| 亚洲欧美中文另类| 国产无遮挡又黄又爽在线观看| 青椒成人免费视频| 久久偷窥视频| 福利成人导航| 欧美一级专区免费大片| 日本美女xxx| 一本色道精品久久一区二区三区 | 九九热这里只有精品免费看| 奴色虐av一区二区三区| av电影天堂一区二区在线观看| 中文字幕成人一区| www.久久.com| 亚洲天堂男人的天堂| 国产视频91在线| 国产精品自拍网站| 一区二区三区四区不卡| 裤袜国产欧美精品一区| 亚洲国产欧美精品| 久久精品免费av| 国产黑丝在线一区二区三区| 夜夜爽99久久国产综合精品女不卡 | 波多野结衣在线播放一区| 91国产精品电影| 亚洲第一天堂在线观看| 日韩久久一区二区| 亚洲一级片网站| 不卡中文一二三区| 国产福利精品在线| av资源网站在线观看| 色美美综合视频| 亚洲精品国产一区黑色丝袜| 老司机一区二区三区| 精品一区二区三区国产| 91超碰国产在线| 精品国产乱码久久久久久图片 | 5858s免费视频成人| 岛国片在线免费观看| 男女男精品视频网| 色就是色欧美| 本网站久久精品| 丝袜亚洲欧美日韩综合| 97人妻精品一区二区三区| 国产精品嫩草99a| 亚洲免费av一区| 91精品电影| 国产成人精品免费视频大全最热| 欧美激情成人动漫| 亚洲精品久久久久中文字幕欢迎你| 免费又黄又爽又色的视频| 成人精品小蝌蚪| 亚洲午夜无码av毛片久久| 国产一区二区三区日韩精品 | 久久一级大片| 色综合久久久久久中文网| 亚洲精品第五页| 五月婷婷激情综合| 欧美成人国产精品一区二区| 蜜臀精品一区二区三区在线观看 | 91禁男男在线观看| 国内不卡的二区三区中文字幕| 欧美美女黄色网| 天堂av一区二区三区在线播放| 国产z一区二区三区| 日本在线视频站| 欧美r级在线观看| 中文字幕激情小说| 中文字幕在线观看一区| 老司机午夜免费福利| 手机精品视频在线观看| 国产a级片免费看| 国产一区福利| 国产精品偷伦视频免费观看国产 | 永久av免费在线观看| 99av国产精品欲麻豆| 亚洲国产成人不卡| 伊人久久影院| 国产精品麻豆va在线播放| 亚洲丝袜一区| 国产亚洲欧洲黄色| 噜噜噜久久,亚洲精品国产品| 色婷婷久久久亚洲一区二区三区| 亚洲女同二女同志奶水| 波多野结衣在线一区| 国产精品久久久毛片| 狠狠色狠狠色综合日日tαg | 国产综合欧美| 色之综合天天综合色天天棕色| 深夜激情久久| 国产精品美女免费| 国产色婷婷在线| 日韩视频在线一区| 巨骚激情综合| 精品久久久久久久久久久院品网| 中文字幕乱码一区二区| 亚洲成人激情av| 三级在线观看免费大全| 国产日韩欧美精品综合| 在线播放av网址| 激情成人午夜视频| 欧美在线观看视频网站| 亚洲国产一区二区三区高清| 国产精品99久久久久久大便| 制服丝袜日韩| 精品卡一卡二| 98视频精品全部国产| 成人性生交大片免费看小说| 91国拍精品国产粉嫩亚洲一区 | 男人舔女人下部高潮全视频| 秋霞电影网一区二区| 青春草国产视频| 亚洲国产成人精品女人| 久青草国产97香蕉在线视频| 国产无遮挡aaa片爽爽| 国产精品视频在线看| 风间由美一二三区av片| 国产精品爽爽爽| www.国产.com| 欧美日韩黄视频| 天堂免费在线视频| 色婷婷亚洲精品| 综合激情网五月| 亚洲美女免费精品视频在线观看| 亚洲av无码一区二区三区在线| 91免费观看在线| 国产精品久久久久久亚洲av| 国产黄色91视频| 一区二区三区日韩欧美| 中文字幕无码不卡免费视频| 国产字幕视频一区二区| 伊人久久大香线蕉av一区| 成全电影播放在线观看国语| 亚洲激情久久久| 成人免费公开视频| 精品久久久久久久久久久久包黑料 | 欧美最新大片在线看| 中文字幕在线播| 日本高清视频一区二区| 欧美一级黄视频| 欧美日韩综合在线免费观看| 中文字幕人妻一区二区在线视频 | 成人小说亚洲一区二区三区| 欧美成人r级一区二区三区| 亚洲高清在线观看视频| 中文字幕日韩一区| 5566中文字幕| 日韩一区中文字幕| 亚洲精品久久久久久国| 中文字幕亚洲欧美在线不卡| 97精品在线播放| 综合婷婷亚洲小说| 亚洲一级生活片| 亚洲黄色小视频| 91视频免费进入| 日本www在线| 色吧影院999| 蜜桃av在线免费观看| 久久艳片www.17c.com| 亚洲电影男人天堂| 欧美激情论坛| re久久精品视频| 中文字幕免费高| 狠狠色丁香久久综合频道| 久久精品免费一区二区| 美女一区二区三区在线观看| 性鲍视频在线观看| 99精品视频一区二区三区| 日本二区在线观看| 91成人国产| 国产精品99导航| 日韩久久99| 成人xxxxx色| 亚洲都市激情| 在线播放 亚洲| 亚洲欧洲日本mm| www.超碰com| 国产在线观看一区二区| 95视频在线观看| 亚洲欧美日韩国产一区二区三区| 亚洲第一中文av| 国产伦精品一区二区三区视频青涩| 国产精品99精品无码视亚| xnxx国产精品| 欧美性猛交xxxxx少妇| 岛国av在线不卡| 国产精品无码在线播放| 亚洲美女中文字幕| h片在线免费| 国产成人高潮免费观看精品| 久久精品66| 91国产精品电影| 欧美久久久网站| 久久大香伊蕉在人线观看热2| 日韩电影二区| 精品国产一二三四区| 麻豆传媒一区二区三区| 午夜av中文字幕| 不卡的看片网站| 91免费公开视频| 色噜噜狠狠色综合中国| 亚洲精品视频一区二区三区| 欧美精品三级| 亚洲最大成人在线观看| 91亚洲大成网污www| 精品无码久久久久成人漫画 | 国产精品9191| 欧美肥妇毛茸茸| 国产在线你懂得| 欧美亚洲在线播放| 国产精品高潮呻吟久久久久| 日韩人妻精品一区二区三区| 日韩国产精品久久| 黄色短视频在线观看| 亚洲一区国产视频| 精品人妻少妇AV无码专区| 三级精品视频久久久久| 成人在线免费av| 日本成人黄色| 久久久精品午夜少妇| 黄色av网址在线观看| 亚洲国产一区二区在线播放| 国产夫绿帽单男3p精品视频| 久久久av一区| **国产精品| 一区中文字幕在线观看| 精品一区二区三区免费观看| jizzjizzjizz国产| 欧美日韩电影在线| 麻豆视频在线观看免费网站| 国产伊人精品在线| 欧美成人激情| 亚洲色图欧美自拍| 成人免费视频在线观看| 国产欧美日韩成人| 欧美成人午夜剧场免费观看| 日韩成人18| 国产va亚洲va在线va| 99久久精品久久久久久清纯| 少妇一级淫片免费放中国| 亚洲摸下面视频| 在线成人视屏 | 99re视频在线播放| 国内精品久久久久久久97牛牛 | www.日韩高清| 欧美高清性猛交| 伦理一区二区三区| 成人午夜视频免费在线观看| 国产日韩欧美激情| 亚洲天堂网在线观看视频| 久久久91精品| 高清一区二区三区| 妺妺窝人体色www在线小说| 久久久久久久综合狠狠综合| 中文在线最新版天堂| 日韩中文字幕久久| 综合伊人久久| 免费av网址在线| 中文字幕中文字幕在线一区| www.国产麻豆| 51久久精品夜色国产麻豆| 成人在线电影在线观看视频| 国产精品自在自线| 亚洲一级片在线观看| 可以免费看污视频的网站在线| 国产人妖伪娘一区91| 欧美日韩专区| 中文字幕第4页| 日韩一级精品视频在线观看| 成人bbav| 人人妻人人澡人人爽精品欧美一区 | 国产精品视频免费观看www| 在线成人直播| 亚洲第一成人网站| 欧美一区二区精品久久911| 色黄视频在线观看| 手机在线视频你懂的| 成人深夜视频在线观看| 中文字幕 国产| 韩国欧美亚洲国产| 亚洲女同另类| 中文字幕 自拍| 精品国产乱码久久|