高效分片上传

原文地址:https://blog.pw131.com

高效分片上传-架构图
在这里插入图片描述

tip 示例代码

前端模块

<template>
  <div>
    <input type="file" @change="handleFileChange" />
    <button @click="uploadFile">开始上传</button>
    <div v-for="progress in uploadProgress" :key="progress.id">
      文件名: {{ progress.name }},进度: {{ progress.progress }}
    </div>
  </div>
</template>
 
<script>
import { ref } from 'vue';
import axios from 'axios';
 
export default {
  data() {
    return {
      file: null,
      uploadProgress: []
    };
  },
  methods: {
    handleFileChange(event) {
      this.file = event.target.files[0];
    },
    uploadFile() {
      const chunkSize = 5 * 1024 * 1024; // 分片大小为5MB,可根据需求调整
 
      const fileSize = this.file.size;
      const totalChunks = Math.ceil(fileSize / chunkSize);
      let postAll = [];
      for (let i = 0; i < totalChunks; i++) {
        const start = i * chunkSize;
        const end = Math.min(start + chunkSize, fileSize);
        const chunk = this.file.slice(start, end);
 
        const formData = new FormData();
        formData.append('file', chunk);
        postAll.push(axios.post('http://localhost:7076/uploadFile', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          onUploadProgress: (event) => {
            const progress = Math.round((start + event.loaded) / fileSize * 100);
            this.uploadProgress[i] = { id: i, name: this.file.name, progress };
          }
        }))
 
      }
      console.log("totalChunks>>>>:" + totalChunks)
      Promise.all(totalChunks)
        .then((responses) => {
         console.log("处理完成")
        })
        .catch((error) => {
          // 处理错误
          console.error(error);
        });
 
    }
 
    // 使用 Promise.all 处理这些请求
 
  }
};
</script>

后端模块

 
@RestController
@Slf4j
public class UploadController {
 
    private static final ReentrantLock LOCK = new ReentrantLock(true);
    private static final Executor EXECUTOR = new ThreadPoolExecutor(12, 12, 5,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadPoolExecutor.DiscardOldestPolicy());
    private static String path = "E:\\temp";
    private static Integer num = 0;
 
    @PostMapping("uploadFile")
    public void uploadFile(MultipartFile file) throws InterruptedException, IOException {
        File dirPath = new File(path);
        if (!dirPath.exists()) {
            dirPath.mkdir();
        }
        String originalFilename = file.getOriginalFilename();
 
        CompletableFuture<Void> completableFutureOne = CompletableFuture.runAsync(() -> {
 
            String test = UUID.randomUUID().toString() + ".mp4";
            String newPath = path + "\\" + test;
            try {
                file.transferTo(new File(newPath));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, EXECUTOR);
 
        CompletableFuture.allOf(completableFutureOne)
                .whenComplete((v, th) ->
                        {
                            num++;
                            log.info("文件存储成功, ====> {}", System.currentTimeMillis());
                        }
                ).join();
    }
 
    @GetMapping("getNum")
    public Integer getNum() throws InterruptedException, IOException {
 
        return num;
    }
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值