为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第19天 断点续传(下)

标签:
Java

一、课程介绍

【课程名称】SpringBoot 2.x 实战仿B站高性能后端项目。
【章节】第四章 4.7 断点续传(下)
【讲师】HELLOSTAR

二、课程内容

分片上传文件

1.分片上传文件实现逻辑

将上传的整个文件预先分片,得到分片的总数量和一些小片的文件。按照分片编号顺序进行上传。
为每个文件生成唯一的MD5加密码,作为Redis中存储的唯一key值。使用Redis缓存数据库来记录当前上传文件保存路径,当前上传的文件分片编号和已上传文件的大小。
逐片上传实际使用的是FastDFS中的修改续传文件的内容方法(modifyFile)每一片文件都执行一次。当文件上传完成,即当前文件分片编号等于分片总编号。则清空Redis中存储的数据。

2. 实现代码

/**
     * 分片上传文件功能
     * 配合Redis使用
     * @param file  上传的文件
     * @param fileMd5   文件加密唯一编号
     * @param sliceNo   分片编号
     * @param totalSliceNo  分片总数量
     * @return
     * @throws Exception
     */
    public String uploadFileBySlices(MultipartFile file, String fileMd5, Integer sliceNo, Integer totalSliceNo) throws Exception {
        if(file == null || sliceNo == null || totalSliceNo == null){
            throw new ConditionException("参数异常!");
        }
        String pathKey = PATH_KEY + fileMd5;
        String uploadedSizeKey = UPLOADED_SIZE_KEY + fileMd5;
        String uploadedNoKey = UPLOADED_NO_KEY + fileMd5;
        String uploadedSizeStr = redisTemplate.opsForValue().get(uploadedSizeKey);
        Long uploadedSize = 0L;
        if(!StringUtil.isNullOrEmpty(uploadedSizeStr)){
            uploadedSize = Long.valueOf(uploadedSizeStr);
        }
        if(sliceNo == 1){ //上传的是第一个分片
            String path = this.uploadAppenderFile(file);
            if(StringUtil.isNullOrEmpty(path)){
                throw new ConditionException("上传失败!");
            }
            redisTemplate.opsForValue().set(pathKey, path);
            redisTemplate.opsForValue().set(uploadedNoKey, "1");
        }else{
            String filePath = redisTemplate.opsForValue().get(pathKey);
            if(StringUtil.isNullOrEmpty(filePath)){
                throw new ConditionException("上传失败!");
            }
            this.modifyAppenderFile(file, filePath, uploadedSize);
            redisTemplate.opsForValue().increment(uploadedNoKey);
        }
        // 修改历史上传分片文件大小
        uploadedSize  += file.getSize();
        redisTemplate.opsForValue().set(uploadedSizeKey, String.valueOf(uploadedSize));
        //如果所有分片全部上传完毕,则清空redis里面相关的key和value
        String uploadedNoStr = redisTemplate.opsForValue().get(uploadedNoKey);
        Integer uploadedNo = Integer.valueOf(uploadedNoStr);
        String resultPath = "";
        if(uploadedNo.equals(totalSliceNo)){
            resultPath = redisTemplate.opsForValue().get(pathKey);
            List<String> keyList = Arrays.asList(uploadedNoKey, pathKey, uploadedSizeKey);
            redisTemplate.delete(keyList);
        }
        return resultPath;
    }

三、课程收获

文件分片上传的实际功能代码。结合Redis使用实现快速的文件分片上传功能。通用性的功能代码,编写起来十分快速和清晰。

四、学习过程

图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消