松鼠的博客

导航

SpringBoot实现对文件的断点续传和秒传

本文断点续传文件思路:

  1. 前端(客户端)需要根据固定大小对文件进行分片,请求后端(服务端)时要带上分片序号和大小;
  2. 服务端创建conf文件用来记录分块位置,conf文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认的0,已上传的就是Byte.MAX_VALUE 127(这步是实现断点续传和秒传的核心步骤);
  3. 服务器按照请求数据中给的分片序号和每片分块大小(分片大小是固定且一样的)算出开始位置,与读取到的文件片段数据,写入文件。

分片上传/断点续传测试验证:

1、分片上传

 

2、断点续传

演示步骤:

a、文件上传一定大小,关闭浏览器,模拟中断,此时上传服务器中会有如下内容:

 

 打开conf文件,会有如下内容:

 

其中小方形为已经上传的块号

b、浏览器继续上传同一份文件

 

 

 

秒传

1、什么是秒传

通俗的说,你把要上传的东西上传,服务器会先做MD5校验,如果服务器上有一样的东西,它就直接给你个新地址,其实你下载的都是服务器上的同一个文件,想要不秒传,其实只要让MD5改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5就变了,就不会秒传了。

2、本文实现的秒传核心逻辑

  a、利用redis的set方法存放文件上传状态,其中key为文件上传的md5,value为是否上传完成的标志位;

  b、当标志位true为上传已经完成,此时如果有相同文件上传,则进入秒传逻辑。如果标志位为false,则说明还没上传完成,此时需要在调用set的方法,保存块号文件记录的路径,其中key为上传文件md5加一个固定前缀,value为块号文件记录路径。

3、核心代码逻辑

private boolean setUploadProgress2Redis(FileUploadRequestDTO param, String uploadDirPath,
      String fileName, File confFile, byte isComplete) {

    RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
    if (isComplete == Byte.MAX_VALUE) {
      redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "true");
      redisUtil.del(FileConstant.FILE_MD5_KEY + param.getMd5());
      confFile.delete();
      return true;
    } else {
      if (!redisUtil.hHasKey(FileConstant.FILE_UPLOAD_STATUS, param.getMd5())) {
        redisUtil.hset(FileConstant.FILE_UPLOAD_STATUS, param.getMd5(), "false");
        redisUtil.set(FileConstant.FILE_MD5_KEY + param.getMd5(),
            uploadDirPath + FileConstant.FILE_SEPARATORCHAR + fileName + ".conf");
      }

      return false;
    }
  }

 

参考文章:http://blog.ncmem.com/wordpress/2023/10/25/springboot%e5%ae%9e%e7%8e%b0%e5%af%b9%e6%96%87%e4%bb%b6%e7%9a%84%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0%e5%92%8c%e7%a7%92%e4%bc%a0/

欢迎入群一起讨论

 

 

posted on 2023-10-25 09:21  Xproer-松鼠  阅读(42)  评论(0编辑  收藏  举报