国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue+springboot上傳大文件

這篇具有很好參考價(jià)值的文章主要介紹了vue+springboot上傳大文件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

眾所周知,上傳大文件是一件很麻煩的事情,假如一條路走到黑,直接一次性把文件上傳上去,對(duì)于小文件是可以這樣做,但是對(duì)于大文件可能會(huì)出現(xiàn)網(wǎng)絡(luò)問題,請(qǐng)求響應(yīng)時(shí)長(zhǎng)等等導(dǎo)致文件上傳失敗,那么這次來教大家如何用vue+srpingboot項(xiàng)目上傳大文件

邏輯

需要做大文件上傳應(yīng)該考慮到如下邏輯:

  1. 大文件上傳一般需要將文件切片(chunk)上傳,然后再將所有切片合并為完整的文件??梢园匆韵逻壿嬤M(jìn)行實(shí)現(xiàn):
  1. 前端在頁面中選擇要上傳的文件,并使用Blob.slice方法對(duì)文件進(jìn)行切片,一般每個(gè)切片大小為固定值(比如5MB),并記錄總共有多少個(gè)切片。
  1. 將切片分別上傳到后端服務(wù),可以使用XMLHttpRequest或Axios等庫發(fā)送Ajax請(qǐng)求。對(duì)于每個(gè)切片,需要包含三個(gè)參數(shù):當(dāng)前切片索引(從0開始)、切片總數(shù)、切片文件數(shù)據(jù)
  1. 后端服務(wù)接收到切片后,保存到指定路徑下的臨時(shí)文件中,并記錄已上傳的切片索引和上傳狀態(tài)。如果某個(gè)切片上傳失敗,則通知前端重傳該切片。
  1. 當(dāng)所有切片都上傳成功后,后端服務(wù)讀取所有切片內(nèi)容并將其合并為完整的文件。可以使用java.io.SequenceInputStream和BufferedOutputStream來實(shí)現(xiàn)文件合并。
  1. 最后返回文件上傳成功的響應(yīng)結(jié)果給前端即可。

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>File Upload</title>
</head>
<body>
    <input type="file" id="fileInput">
    <button onclick="upload()">Upload</button>
    <script>
        function upload() {
            let file = document.getElementById("fileInput").files[0];
            let chunkSize = 5 * 1024 * 1024; // 切片大小為5MB
            let totalChunks = Math.ceil(file.size / chunkSize); // 計(jì)算切片總數(shù)
            let index = 0;
            while (index < totalChunks) {
                let chunk = file.slice(index * chunkSize, (index + 1) * chunkSize);
                let formData = new FormData();
                formData.append("file", chunk);
                formData.append("index", index);
                formData.append("totalChunks", totalChunks);
                // 發(fā)送Ajax請(qǐng)求上傳切片
                $.ajax({
                    url: "/uploadChunk",
                    type: "POST",
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function () {
                        if (++index >= totalChunks) {
                            // 所有切片上傳完成,通知服務(wù)端合并文件
                            $.post("/mergeFile", {fileName: file.name}, function () {
                                alert("Upload complete!");
                            })
                        }
                    }
                });
            }
        }
    </script>
</body>
</html>

后端

controller層:

@RestController
public class FileController {

    @Value("${file.upload-path}")
    private String uploadPath;

    @PostMapping("/uploadChunk")
    public void uploadChunk(@RequestParam("file") MultipartFile file,
                            @RequestParam("index") int index,
                            @RequestParam("totalChunks") int totalChunks) throws IOException {
        // 以文件名+切片索引號(hào)為文件名保存切片文件
        String fileName = file.getOriginalFilename() + "." + index;
        Path tempFile = Paths.get(uploadPath, fileName);
        Files.write(tempFile, file.getBytes());
        // 記錄上傳狀態(tài)
        String uploadFlag = UUID.randomUUID().toString();
        redisTemplate.opsForList().set("upload:" + fileName, index, uploadFlag);
        // 如果所有切片已上傳,則通知合并文件
        if (isAllChunksUploaded(fileName, totalChunks)) {
            sendMergeRequest(fileName, totalChunks);
        }
    }

    @PostMapping("/mergeFile")
    public void mergeFile(String fileName) throws IOException {
        // 所有切片均已成功上傳,進(jìn)行文件合并
        List<File> chunkFiles = new ArrayList<>();
        for (int i = 0; i < getTotalChunks(fileName); i++) {
            String chunkFileName = fileName + "." + i;
            Path tempFile = Paths.get(uploadPath, chunkFileName);
            chunkFiles.add(tempFile.toFile());
        }
        Path destFile = Paths.get(uploadPath, fileName);
        try (OutputStream out = Files.newOutputStream(destFile);
             SequenceInputStream seqIn = new SequenceInputStream(Collections.enumeration(chunkFiles));
             BufferedInputStream bufIn = new BufferedInputStream(seqIn)) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bufIn.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        }
        // 清理臨時(shí)文件和上傳狀態(tài)記錄
        for (int i = 0; i < getTotalChunks(fileName); i++) {
            String chunkFileName = fileName + "." + i;
            Path tempFile = Paths.get(uploadPath, chunkFileName);
            Files.deleteIfExists(tempFile);
            redisTemplate.delete("upload:" + chunkFileName);
        }
    }

    private int getTotalChunks(String fileName) {
        // 根據(jù)文件名獲取總切片數(shù)
        return Objects.requireNonNull(Paths.get(uploadPath, fileName).toFile().listFiles()).length;
    }

    private boolean isAllChunksUploaded(String fileName, int totalChunks) {
        // 判斷所有切片是否已都上傳完成
        List<String> uploadFlags = redisTemplate.opsForList().range("upload:" + fileName, 0, -1);
        return uploadFlags != null && uploadFlags.size() == totalChunks;
    }

    private void sendMergeRequest(String fileName, int totalChunks) {
        // 發(fā)送合并文件請(qǐng)求
        new Thread(() -> {
            try {
                URL url = new URL("http://localhost:8080/mergeFile");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
                OutputStream out = conn.getOutputStream();
                String query = "fileName=" + fileName;
                out.write(query.getBytes());
                out.flush();
                out.close();
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
                while (br.readLine() != null) ;
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
}

其中,file.upload-path為文件上傳的保存路徑,可以在application.properties或application.yml中進(jìn)行配置。同時(shí)需要添加RedisTemplate的Bean以便記錄上傳狀態(tài)。

RedisTemplate配置

如果需要使用RedisTemplate,需要引入下方的包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

同時(shí)在yml配置redis的信息

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0

然后在自己的類中這樣使用

@Component
public class myClass {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

注意事項(xiàng)

需要控制每次上傳的切片大小,以兼顧上傳速度和穩(wěn)定性,避免占用過多服務(wù)器資源或因網(wǎng)絡(luò)不穩(wěn)定而導(dǎo)致上傳失敗。

切片上傳存在先后順序,需要保證所有切片都上傳完成后再進(jìn)行合并,否則可能會(huì)出現(xiàn)文件不完整或者文件合并錯(cuò)誤等情況。

上傳完成后需要及時(shí)清理臨時(shí)文件,避免因?yàn)檎加眠^多磁盤空間而導(dǎo)致服務(wù)器崩潰??梢栽O(shè)置一個(gè)定期任務(wù)來清理過期的臨時(shí)文件。

結(jié)語

以上就是vue+springboot上傳大文件的邏輯文章來源地址http://www.zghlxwxcb.cn/news/detail-423069.html

到了這里,關(guān)于vue+springboot上傳大文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • vue+springboot 上傳文件、圖片、視頻,回顯到前端。

    vue+springboot 上傳文件、圖片、視頻,回顯到前端。

    預(yù)覽: 視頻: 分成兩部,1.通過前端將文件的基本信息傳送到后端進(jìn)行儲(chǔ)存,返回已儲(chǔ)存的文件id,2.再將文件發(fā)送到后端儲(chǔ)存。 儲(chǔ)存文件信息 上傳文件對(duì)象 這個(gè)我放在d盤下面,需要修改映射路徑

    2023年04月19日
    瀏覽(26)
  • springboot整合Minio + vue 實(shí)現(xiàn)文件分片上傳(完整代碼)

    springboot整合Minio + vue 實(shí)現(xiàn)文件分片上傳(完整代碼)

    網(wǎng)上關(guān)于minio分片上傳的資料不太詳細(xì),缺斤少兩,所以我基于他們的代碼做了一些修改,demo能夠正常運(yùn)行起來,但是偶爾也會(huì)發(fā)生一些小bug,不過這些都無傷大雅,最終目的是理解代碼背后的邏輯和流程 流程: 前端獲取生成文件MD5,發(fā)送至后臺(tái)判斷是否有該文件緩存,有

    2024年02月02日
    瀏覽(26)
  • 【java】java實(shí)現(xiàn)大文件的分片上傳與下載(springboot+vue3)

    【java】java實(shí)現(xiàn)大文件的分片上傳與下載(springboot+vue3)

    源碼: https://gitee.com/gaode-8/big-file-upload 演示視頻 https://www.bilibili.com/video/BV1CA411f7np/?vd_source=1fe29350b37642fa583f709b9ae44b35 對(duì)于超大文件上傳我們可能遇到以下問題 ? 大文件直接上傳,占用過多內(nèi)存,可能導(dǎo)致內(nèi)存溢出甚至系統(tǒng)崩潰 ? 受網(wǎng)絡(luò)環(huán)境影響,可能導(dǎo)致傳輸中斷,只能重

    2024年02月02日
    瀏覽(29)
  • springboot整合vue2-uploader文件分片上傳、秒傳、斷點(diǎn)續(xù)傳

    springboot整合vue2-uploader文件分片上傳、秒傳、斷點(diǎn)續(xù)傳

    vue-simple-uploader 是基于 simple-uploader.js 封裝的vue上傳插件。它的優(yōu)點(diǎn)包括且不限于以下幾種: 支持文件、多文件、文件夾上傳;支持拖拽文件、文件夾上傳 可暫停、繼續(xù)上傳 錯(cuò)誤處理 支持“秒傳”,通過文件判斷服務(wù)端是否已存在從而實(shí)現(xiàn)“秒傳” 分片上傳 支持進(jìn)度、預(yù)估

    2024年02月06日
    瀏覽(35)
  • 【萬字長(zhǎng)文】Vue+SpringBoot實(shí)現(xiàn)大文件秒傳、斷點(diǎn)續(xù)傳和分片上傳完整教程(提供Gitee源碼)

    前言:最近在實(shí)際項(xiàng)目中碰到一個(gè)需求,客戶可能會(huì)上傳比較大的文件,如果采用傳統(tǒng)的文件上傳方案可能會(huì)存在服務(wù)器壓力大、資源浪費(fèi)甚至內(nèi)存溢出的一些安全風(fēng)險(xiǎn),所以為了解決一系列問題,需要采用新的技術(shù)方案來實(shí)現(xiàn)大文件的上傳;空閑的時(shí)候參考了網(wǎng)上的一些相

    2024年02月12日
    瀏覽(23)
  • SpringBoot整合hdfs,實(shí)現(xiàn)文件上傳下載刪除與批量刪除,以及vue前端發(fā)送請(qǐng)求,實(shí)現(xiàn)前后端交互功能;

    SpringBoot整合hdfs,實(shí)現(xiàn)文件上傳下載刪除與批量刪除,以及vue前端發(fā)送請(qǐng)求,實(shí)現(xiàn)前后端交互功能;

    部分工具類代碼參考文章:https://blog.csdn.net/qq_27242695/article/details/119683823 前端實(shí)現(xiàn)效果 HDFSController HDFS FileInterface (文件接口) HDFS FileImplService (文件接口實(shí)現(xiàn)類) HDFSConfig(從yaml讀取文件) HDFSUTils 前端vue代碼:

    2024年02月16日
    瀏覽(130)
  • Springboot實(shí)現(xiàn)上傳文件,并實(shí)現(xiàn)調(diào)用第三方接口post請(qǐng)求多文件上傳文件

    項(xiàng)目過程中,經(jīng)常會(huì)有和第三方接口打交道的過程,今天實(shí)現(xiàn)調(diào)用第三方上傳文件的接口??! 通常拿到第三方的接口文檔的時(shí)候,不是第一時(shí)間先寫代碼,而是詳細(xì)閱讀接口文檔。若接口需要第三方提供的基本參數(shù),例如signkey, secrect等,也可以是其他的,查看文檔里是否提

    2024年02月16日
    瀏覽(19)
  • SpringBoot之文件上傳

    SpringBoot之文件上傳

    1、文件上傳原理?? ?2、SpirngBoot實(shí)現(xiàn)文件上傳功能?? 3、SpirngBoot實(shí)現(xiàn)文件上傳功能?? 4、測(cè)試??

    2024年01月22日
    瀏覽(53)
  • SpringBoot+前端文件分片上傳

    SpringBoot+前端文件分片上傳

    在日常生活中,文件上傳相關(guān)的操作隨處可見,大到處理大數(shù)據(jù)量的文件,小到頭像上傳,都離不開文件上傳操作,但是當(dāng)一個(gè)文件的大小超過了某個(gè)閾值時(shí),這個(gè)文件的上傳過程就會(huì)變得及其的慢,且會(huì)消耗大量網(wǎng)絡(luò)資源,這是我們不愿意看到的,所以,文件分片上傳孕育而生。 文件分

    2024年02月19日
    瀏覽(21)
  • 【SpringBoot】文件上傳到阿里云

    實(shí)例:蒼穹外賣 oss 相關(guān)配置: application.yml application-dev.yml(這里不用橫杠分隔,用駝峰命名也是可以的,SpringBoot會(huì)自動(dòng)轉(zhuǎn)換) 配置屬性類AliOssProperties : AliOssUtil : OssConfiguration : 文件上傳Controller

    2024年02月03日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包