前端+后端实现分片上传(断点续传/极速秒传)(代码片段)

ps酷教程 ps酷教程     2023-04-11     688

关键词:

先记录下,后面有时间再去实现
可参考链接:vue上传大文件/视频前后端(java)代码

前端 + 后端 实现分片上传(断点续传/极速秒传)

前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当接受完最后一个分片(分片索引等于分片总数,分片索引从1开始),就合并分片成完成的文件。前端需要递归上传,并显示加载动画和根据分片完成数量显示进度条

临时demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="http://www.baidu.com/a">
        <input type="file" type="hidden" id="file"><!-- 隐藏这个原生的上传文件按钮 -->
        <button type="button" id="btn">触发上传</button></button><!-- 使用它来触发选择图片动作 -->
    </form>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script>
    /* 监听选择图片的事件 */
    document.querySelector('#file').onchange =  (e)=>
        console.log('改变了');
        console.log(this); // 这里的this变成了Window, 因为写成了箭头函数。
        console.dir(e.target); 

        // 选择了一个文件,所以数组只有一个元素
        console.log(e.target.files); // FileList 0: File, length: 1

        console.log(e.target.files[0]); // File name: 'GIF 2023-4-1 18-14-01.gif', lastModified: 1680344051705, lastModifiedDate: Sat Apr 01 2023 18:14:11 GMT+0800 (中国标准时间), webkitRelativePath: '', size: 242914, …

        upload(e.target.files[0])

        document.querySelector('#file').value = '' // 让下次即使选择同一个文件仍能触发onchange事件
    

    function upload(file) 
        console.log(file instanceof Blob); // true, 而Blob中有个slice方法,可以对文件进行分片
        let formData = new FormData()

        let shardSize = 10 * 1024 * 1024
        let shardIndex = 1
        let start = shardSize * shardIndex
        let end = Math.min(file.size, start + shardSize)
        console.log(start,end);
        formData.append('mfile', file.slice(start,end))

        // 携带数据请求后台
        $.ajax(
            url: 'http://127.0.0.1:8083/article/uploadImg',
            type: 'POST',
            data: formData,
            contentType: false,
            processData: false,
            cache: false,
            success: function (data) 
                if (data.success) 
                    alert('添加成功');
                 else 
                    alert('添加失败');
                
            
        );
    

    /* 点的是#btn,但是我们要触发#file文件上传 */
    document.querySelector('#btn').onclick = function()
        document.querySelector('#file').click()
    
</script>
</html>
@PostMapping("uploadImg")
public Result uploadImg(@RequestParam("mfile") MultipartFile mfile) throws IOException 
    String filename = mfile.getOriginalFilename();
    mfile.transferTo(new File("D:\\\\Projects\\\\vue-springboot\\\\src\\\\main\\\\resources\\\\static\\\\img\\\\"+filename));
    return Result.ok(filename);

spring:
  servlet:
    multipart:
      max-file-size: 50MB
      max-request-size: 50MB

oss 将前面的分片上传改为oss里的追加上传

public static void main(String[] args) throws IOException 
        
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "xxx";
        String accessKeySecret = "yyy";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "test-zzhua";

        String objectName = "video/juc.mp4";

        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        ObjectMetadata meta = new ObjectMetadata();
        meta.setObjectAcl(CannedAccessControlList.PublicRead);


        RandomAccessFile raFile = new RandomAccessFile(new File("D:\\\\Projects\\\\vue-springboot\\\\src\\\\main\\\\resources\\\\static\\\\img\\\\juc.mp4"), "r");

        long totalLen = raFile.length();

        // 定义每次追加上传的大小 3M
        long everyLen = 3 * 1024 * 1024;

        long accLen = 0;


        byte[] bytes = new byte[5 * 1024]; // 缓冲数组5k

        while (true) 

            // 找到上次读取的位置
            raFile.seek(accLen);

            boolean finish = false;

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            // 当前读取累积3M, 或不够3M就读完了
            int currLen = 0;

            while (true) 
                int readLen = raFile.read(bytes);
                if (readLen == -1) 
                    finish = true;
                    break;
                
                currLen += readLen;
                baos.write(bytes, 0, readLen);
                if (currLen >= everyLen) 
                    break;
                
            

            // 发起追加请求
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, bais,meta);
            appendObjectRequest.setPosition(accLen);
            ossClient.appendObject(appendObjectRequest);

            if (finish) 
                break;
            

            accLen += currLen;

        


    

md5大文件计算

javascript实现

参考:SpringBoot大文件上传–前端计算文件的MD5

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/spark-md5/3.0.2/spark-md5.js"></script>
</head>
<body>
    <form id="from" method="post" action="/upload" enctype="multipart/form-data">
        <table>
            <tr>
                <td>
                    <input id="md5" name="md5">
                    <input id="file" name="upload" type="file">
                    <input id="submit" type="submit" value="上传">
                </td>
            </tr>
        </table>
    </form>

</body>
<script>
    //注意此方法引用了SparkMD5库 library:https://github.com/satazor/SparkMD5
    //监听文本框变化
    document.getElementById("file").addEventListener("change", function() 
        //声明必要的变量
        chunks=0;
        currentChunk=0;
        var fileReader = new FileReader();//一个用来读取文件的对象
        //文件分割方法(注意兼容性)
        blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice,
            file = document.getElementById("file").files[0],
            //文件每块分割2M,计算分割详情
            chunkSize = 2097152,
            chunks = Math.ceil(file.size / chunkSize),//文件分成了几块
            currentChunk = 0,//当前处理的第几块
            
            spark = new SparkMD5();//创建md5对象(基于SparkMD5)

       //每块文件读取完毕之后的处理
        fileReader.onload = function(e) 
            console.log("读取文件", currentChunk + 1, "/", chunks);
            //每块交由sparkMD5进行计算
            spark.appendBinary(e.target.result);
            currentChunk++;
            //如果文件处理完成计算MD5,如果还有分片继续处理
            if (currentChunk < chunks) 
                loadNext();
             else 
                md5=spark.end();//最终的MD5
                console.log("MD5:"+md5);
            
        ;

        //处理单片文件的上传
        function loadNext() 
            var start = currentChunk * chunkSize,
                end = start + chunkSize >= file.size ? file.size : start + chunkSize;
            fileReader.readAsBinaryString(blobSlice.call(file, start, end));
            //blobSlice.call(file, start, end)每次执行到blobSlice的时候就会跳转到blobSlice定义的地方,可以理解为一个循环
        
        loadNext();
    );
</script>

</html>

java实现

参考:详解JAVA中获取文件MD5值的四种方法
须引入commons-codec包

String s = DigestUtils.md5Hex(new FileInputStream(new File("D:\\\\documents\\\\尚硅谷谷粒学院项目视频教程\\\\6 - What If I Want to Move Faster.mp4")));
ystem.out.println(s);

springboot分片上传断点续传大文件极速秒传功能,这篇都帮你搞定!(典藏版)...(代码片段)

...呢,答案有的,就是下边要介绍的几种上传方式1.分片上传1.1什么是分片上传分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为Part)来进行分别上传,... 查看详情

大文件分片上传,断点续传,秒传实现

前段时间做视频上传业务,通过网页上传视频到服务器。视频大小小则几十M,大则1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中... 查看详情

java如何实现大文件分片上传,断点续传和秒传

Java如何实现大文件分片上传,断点续传和秒传引言概念秒传1、什么是秒传2、实现秒传常见做法分片上传1、什么是分片上传2、分片上传的场景断点续传1、什么是断点续传2、应用场景3、实现断点续传的核心逻辑实现思路前置知识... 查看详情

如何实现大文件上传:秒传断点续传分片上传(代码片段)

...你多加几个字,MD5就变了,就不会秒传了.2、本文实现的秒传核心逻辑a、利用redis的set方法存放文件上传状态,其中key为文件上传的md5,value为是否上传完成的标志位,b、当标志位true为上传已经完成&#x 查看详情

如何实现大文件上传:秒传断点续传分片上传(代码片段)

...你多加几个字,MD5就变了,就不会秒传了.2、本文实现的秒传核心逻辑a、利用redis的set方法存放文件上传状态,其中key为文件上传的md5,value为是否上传完成的标志位,b、当标志位true为上传已经完成&#x 查看详情

10g大文件上传最全方案:秒传断点续传分片上传,包教会!

上一篇:麻了!Fastjson再曝反序列化漏洞。。前言文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进... 查看详情

jsp利用webuploader实现超大文件分片上传断点续传

...调整和配置,自己将大小都以501M来进行限制。第一步:前端修改由于项目使用的是BJUI前端框架,并没有使用框架本身的文件上传控件,而使用的基于jQuery的Uploadify 查看详情

vue超大文件上传解决方案:分片断点上传

...这些都是web开发所必须直面的。本文给出的解决方案是:前端实现数据流分片长传,后面接收完毕后合并文件的思路。实现文件夹上传,要求:服务端保留层级结构,支持10w级别的文件夹上传。大文件上传及断点续传,要求:支... 查看详情

前端实现大文件上传分片上传断点续传

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情

搭建fastdfs服务,及单机redis服务,springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传文件和批量上传(代码片段)

前言搭建单机redis服务,结合fastdfs,springboot实现h5与fastdfs之间的断点续传,大文件上传,秒传。技术采用:webuploader+springboot+redis+fastdfs(服务端)+FastDFS_Client。本文所需实现工具,皆在此包中https://download. 查看详情

局域网超大文件上传和断点续传的实现

...这些都是web开发所必须直面的。本文给出的解决方案是:前端实现数据流分片长传,后面接收完毕后合并文件的思路。实现文件夹上传,要求:服务端保留层级结构,支持10w级别的文件夹上传。大文件上传及断点续传,要求:支... 查看详情

局域网超大文件上传和断点续传的实现

...这些都是web开发所必须直面的。本文给出的解决方案是:前端实现数据流分片长传,后面接收完毕后合并文件的思路。实现文件夹上传,要求:服务端保留层级结构,支持10w级别的文件夹上传。大文件上传及断点续传,要求:支... 查看详情

支持ie低版本的上传大文件切割上传断点续传秒传

...分批上传,再组合成一个大文件。支持断点续传,MD5校验实现妙传功能,支 查看详情

阿里云oss文件上传(分片上传断点续传)前后端实现(代码片段)

...考官方文档:阿里云OSS。出于账号安全的考虑,前端使用OSS服务需要走临时授权,即拿一个临时凭证(STSToken)去调用aliyun-ossSDK。关于临时授权请参考:RAM和STS介绍,RAM子账号,STS临时授权访问OSS... 查看详情

阿里云oss文件上传(分片上传断点续传)前后端实现(代码片段)

...考官方文档:阿里云OSS。出于账号安全的考虑,前端使用OSS服务需要走临时授权,即拿一个临时凭证(STSToken)去调用aliyun-ossSDK。关于临时授权请参考:RAM和STS介绍,RAM子账号,STS临时授权访问OSS... 查看详情

项目难点——断点续传分片上传(代码片段)

...的是断点续传。断点续传效果图:流程如下:1、前端上传前先把文件分成块2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传3、各分块上传完成最后在服务端合并文件2.2分片与合并测试①文... 查看详情

实战篇:断点续传?文件秒传?手撸大文件上传(代码片段)

...大家能够喜欢。开味菜最近接到一个新的需求,需要上传2G左右的视频文件,用测试环境的OSS试了一下,上传需要十几分钟,再考虑到公司的资源问题,果断放弃该方案。一提到大文件上传,我最先想到的... 查看详情

前端js实现文件的断点续传后端php文件接收

http://www.jb51.net/article/94732.htm 查看详情