SpringBoot Vue 实现文件分片上传

SpringBoot Vue 实现文件分片上传


文章目录

  • SpringBoot Vue 实现文件分片上传
  • 前言
  • 一、使用场景
  • 二、使用步骤
    • 1.前端上传分片
    • 2.后端接收分片
    • 3.测试上传效果


前言

分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为Part)来进行分别上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。


一、使用场景

1、大文件上传
2、网络环境环境不好,存在需要重传风险的场景(马上快传完了,结果网络不稳定,又要重头开始,心态爆炸!!!)

二、使用步骤

1.前端上传分片


实现思路,前端在文件上传的时候先计算文件根据片的大小计算分片数、记录当前分片数,再一起传给后端。

这里前端只是简单写一下,没有引入Elementui

  <div>
    <input type="file" @change="selectFile">
    <button @click="upload">分片上传</button>
  </div>

data() {
    return {
      file: null,
      chunk: 0,  // 当前分片
      chunks: 0, // 总分片数
      name: ''   // 文件名
    }
  },
  methods: {
    // 可以根据后端配置的上传文件大小进行判断是否需要分片
    selectFile(e) {
      this.file = e.target.files[0]
      this.name = this.file.name
      // 分片大小根据实际需要 调整 可以配置在前端配置文件中
      this.chunks = Math.ceil(this.file.size / 1024 / 1024 / 2) // 2MB一片
    },
    upload() {
      // 现将文件分片
      const formData = new FormData()
      formData.append('file', this.file.slice(this.chunk * 1024 * 1024 * 2, (this.chunk + 1) * 1024 * 1024 * 2))
      formData.append('chunk', this.chunk)
      formData.append('chunks', this.chunks)
      formData.append('name', this.name)
      // 然后递归调用文件上传接口
      axios.post('http://localhost:8090/file/v1/upload/splitFileUpload', formData)
          .then(() => {
            this.chunk++
            if (this.chunk < this.chunks) {
              this.upload()
            }
          })
    }
  }

2.后端接收分片


  1. 接收分片文件、分片序号、总分片数和文件名;
  2. 保存上传的分片文件;
  3. 最后一个分片上传完成后,合并所有分片为完整文件;
  4. 合并完成后删除分片文件;(可以使用Apache Commons FileUtils工具类等)
  5. 返回成功响应。
 /**
     * 分片上传
     *
     * @param file   文件
     * @param chunk  块
     * @param chunks 块
     * @param name   名字
     * @return {@link ResponseEntity}<{@link String}>
     * @throws IOException ioexception
     */
    @PostMapping("/splitFileUpload")
    public ResponseEntity<String> splitFileUpload(@RequestParam("file") MultipartFile file,
                                                  @RequestParam("chunk") int chunk,
                                                  @RequestParam("chunks") int chunks,
                                                  @RequestParam("name") String name) throws IOException {
        String folder = uploadDir;
        File dir = new File(folder);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String path = folder + name + "_" + chunk + ".part";
        try {
            file.transferTo(new File(path));
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件保存失败!");
        }
        if (chunk == chunks - 1) {
            // 合并所有分片
            File[] content = new File[chunks];
            for (int i = 0; i < chunks; i++) {
                content[i] = new File(folder + name + "_" + i + ".part");
            }
            FileUtil.mergeFile(content, new File(folder + name));
            // 删除分片文件
            for (int i = 0; i < chunks; i++) {
                new File(folder + name + "_" + i + ".part").delete();
            }
        }
        return ResponseEntity.ok("上传成功");
    }

注意点
Tomcat默认文件大小有限制,需要在配置文件中修改

spring:
  servlet:
    multipart:
      # 最大文件上传大小配置 防止出现The field file exceeds its maximum permitted size of 1048576 bytes错误
      max-file-size: 50MB
      max-request-size: 50MB

3.测试上传效果

你可能感兴趣的:(spring,boot,vue)