前端大文件分片上传原理

 <!-- spark-md5 hash值计算插件 -->
    <script src="spark-md5.min.js"></script>
    <input type="file">
    <script>
    /*
    * 补充说明:
    *     大文件分片上传,计算hash值时,文件很大时运算时间非常长,因为它是cpu特别密集的任务,    
    *     所以非常消耗cpu,所以最好单开一个线程做文件处理
    *  扩展:单开线程需要了解web work知识
    */
        const inp = document.querySelector('input');
         //这里须要用到File的slice( )方法,如下是兼容写法
        const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
        inp.onchange = async (e) => {
            const file = inp.files[0]
            if (!file) {  // 判断是否获取到文件,取到直接return回去
                return;
            }
            /*
            const piece = file.slice(0, 100);// 0-99个字节的数据
            console.log(piece) // 输出:Blob {size: 100, type: ''}
            */
            const chunks = createChunks(file, 10 * 1024 * 1024) // 分片10M
            /*
            * 拿到分片数据可以利用接口的方式上传
            */
             console.log(chunks)// 获取到分片后的文件片段数据 
            const result = await hash(chunks)
            /*
            * 拿到文件的唯一hash值,就可以配合后端,做文件暂停、继续、网络异常导致的上传失败,下次继续上传
            */
            console.log(result) // 拿到文件的唯一hash值
        }
        function hash(chunks) { // 计算文件的hash值
            return new Promise((resolve, reject) => {
                const spark = new SparkMD5() //建立SparkMD5的实例
                function _read(i) {
                    if (i >= chunks.length) { // i 大于等于分片数组的长度返回文件计算出的唯一Hash值
                        resolve(spark.end()) // 完成计算,返回结果
                        return;//
                    }
                    const blob = chunks[i] // 获取文件的分片数组中的一个文件
                    const reader = new FileReader(); //建立FileReader的实例
                    reader.onload = e => { // FileReader的load事件,当文件读取完毕时触发
                        const bytes = e.target.result // 读取到字节的数组
                        spark.append(bytes) // spark-md5 // 开始计算Hash值
                        _read(i + 1)// 递归
                    }
                    reader.readAsArrayBuffer(blob);//经过fileReader读取文件二进制码
                }
                _read(0)// 初始计算
            })
        }
        /*
        * function 文件切片返回result
        * file:文件内容
        * chunksSize:文件切片的大小(字节)
        */
        function createChunks(file, chunkSize) {          
            const result = []
            for (let i = 0; i < file.size; i += chunkSize) {
                result.push(blobSlice.call(file.slice(i, i + chunkSize)))
            }
            return result
        }
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初一Y

你的鼓励将是我创造的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值