SpringBoot实现文件分片断点续传功能(后端篇)

最近想实现一下分片上传的功能,文件分片上传就能实现断点续传了,数据库记录也能保证秒传功能的实现。记录一下宝宝demo。
前端部分可以看看这篇文章:Springboot实现文件分片断点续传功能(前端篇)
项目代码已上传至GitHub。 https://github.com/huiluczP/segment_upload

整体思路

  1. 首先利用数据库存储文件信息,包括文件物理地址,分片接收进程和对应的md5码。利用md5码可以判断当前上传文件是否在服务器中存在(实现秒传),利用分片接收Index可以判断现在应该上传。
  2. 前端ajax获取文件存在与否的信息,几种情况:
    (1) 不存在,则创建数据库记录,成功后调用分片1的上传。
    (2) 存在,Index和总分片数量相同,秒传成功显示结果。
    (3) 存在,但index小于总分片数量,调用分片index的上传。
  3. 分片在前端根据分片Index计算起点末尾,slice切割,ajax调用上传传到服务器并存储。当前分片传递成功,ajax接收success信息,串行进行index+1的分片的上传。

具体后端实现使用的是springboot+mybatis。

数据库设计和持久化操作

主要就是segment_file表,用来存储文件对应信息。
其中file_path表示文件最终的物理路径(未完成的分片文件也会存储在parent文件夹中)。
file_name是uuid,segment_index是已经完成的分片数量,segment_total为总的分片数量。
md5_key是文件对应的唯一key,实现中是在前端计算的。

CREATE TABLE `segment_file` (
  `id` int NOT NULL AUTO_INCREMENT,
  `file_path` varchar(200) NOT NULL,
  `file_name` varchar(200) DEFAULT NULL,
  `size` int DEFAULT NULL,
  `segment_index` int DEFAULT NULL,
  `segment_size` int DEFAULT NULL,
  `segment_total` int DEFAULT NULL,
  `md5_key` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

持久化类 SegmentFile

public class SegmentFile implements Serializable {
   
    private static final long serialVersionUID = -1937877331354085546L;
    private int id;
    private String filePath;
    private String fileName;
    private int size;
    private int segmentIndex;
    private int segmentSize;
    private int segmentTotal;
    private String md5Key;
	
	getter…
	setter…
}

Mapper接口,这边使用注解进行mybatis sql语句的配置.

@Mapper
public interface SegmentFileMapper {
   

    // 获取对应的分片文件实体类
    @Select("select * from segment_file where md5_key = #{key}")
    @Results(id="segmentFileResult",value={
   
            @Result(id=true, column = "id",property = "id"),
            @Result(column = "file_path",property = "filePath"),
            @Result(column = "file_name",property = "fileName"),
            @Result(column = "size",property = "size"),
            @Result(column = "segment_index",property = "segmentIndex"),
            @Result(column = "segment_size",property = "segmentSize"),
            @Result(column = "segment_total",property = "segmentTotal"),
            @Result(column = "md5_key",property = "md5Key")
    })
    public List<SegmentFile> getSegmentFileByKey(String key);

    // 添加对应的文件实体类
    @Insert("insert into segment_file(id,file_path,file_name," +
            "size,segment_index,segment_size,segment_total,md5_key) " +
            "values(#{id},#{filePath},#{fileName},#{size},#{segmentIndex}," +
            "#{segmentSize},#{segmentTotal},#{md5Key})")
    public int insertSegmentFile(SegmentFile segmentFile);

    // 主要用来更新分片信息
    @Update({
   "update segment_file set " +
            "file_path = #{filePath},file_name = #{fileName},size = #{size}," +
            "segment_index = #{segmentIndex}, segment_size = #{segmentSize}," +
            "segment_total = #{segmentTotal}, md5_key = #{md5Key}" +
            "where id = #{id}" })
    public int updateSegmentFile(SegmentFile segmentFile);
}

特别的,我们对文件保存路径在配置文件application.yml中进行设置。同时,为了实现大文件分片的上传,关闭springboot的文件上传大小限制。数据库配置就不赘述了。

spring:
  servlet:
    multipart:
      max-file-size: -1
      max-request-size: -1
file:
  save-path: E:/file/

工具类实现

FileUtil为文件处理工具类,包括利用uuid和md5码的文件名生成。特别的,我们将原文件的名称后加上#和分片序号作为对应分片文件的名称。

// 工具类
// 文件名生成
public class FileUtil {
   
    public static String getFileNameWithoutSuffix(String fileName){
   
        int suffixIndex = fileName.lastIndexOf('.');
        if(suffixIndex<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值