28-大文件上传(了解)

news/2024/5/14 18:30:59/文章来源:https://blog.csdn.net/weixin_44423378/article/details/130947774

一、是什么?

🚗🚗🚗不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂。
文件上传简单,文件变大就复杂
上传时,以下几个注意点会影响用户体验

  • 服务器处理数据的能力
  • 请求超时
  • 网络波动
    上传时间会变长,高频次文件上传失败,失败后又需要重新上传等等
    为了解决上述问题,我们需要对大文件上传单独处理
    分片上传断点续传两个概念

二、分片上传

🚓🚓
分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(Part)来进行分片上传
在这里插入图片描述

上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件

大致流程如下:
1,将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;
2.初始化一个分片上传任务,返回本次分片上传唯一标识;
3,按照一定的策略(串行或并行)发送各个分片数据块;
4,发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件

断点续传

🚕🚕
断点续传指的是在下载上传时,将下载或上传任务人为的划分为几个部分

每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度
一般实现方式有两种:

  • 服务器端返回,告知从哪开始
  • 浏览器端自行处理

上传过程中将文件在服务器写为临时文件,等全部写完了(文件上传完),将此临时文件重命名为正式文件即可;

如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可

二、实现思路

整体思路,拿到文件,保存文件唯一标识,切割文件,分段上传,每次上传一段,根据唯一标识判断文件上传进度,直到文件的全部片段上传完毕

在这里插入图片描述
下面的内容都是伪代码

读取文件内容:

const input = document.querySelector('input');
input.addEventListener('change', function() {var file = this.files[0];
});

可以使用md5实现文件的唯一

const md5code = md5(file);

然后开始对文件进行分割

var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.addEventListener("load", function(e) {//每10M切割一段,这里只做一个切割演示,实际切割需要循环切割,var slice = e.target.result.slice(0, 10*1024*1024);
});

h5上传一个(一片)

const formdata = new FormData();
formdata.append('0', slice);
//这里是有一个坑的,部分设备无法获取文件名称,和文件类型,这个在最后给出解决方案
formdata.append('filename', file.filename);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {//xhr.responseText
});
xhr.open('POST', '');
xhr.send(formdata);
xhr.addEventListener('progress', updateProgress);
xhr.upload.addEventListener('progress', updateProgress);function updateProgress(event) {if (event.lengthComputable) {//进度条}
}

这里给出常见的图片和视频的文件类型判断

function checkFileType(type, file, back) {
/**
* type png jpg mp4 ...
* file input.change=> this.files[0]
* back callback(boolean)
*/var args = arguments;if (args.length != 3) {back(0);}var type = args[0]; // type = '(png|jpg)' , 'png'var file = args[1];var back = typeof args[2] == 'function' ? args[2] : function() {};if (file.type == '') {// 如果系统无法获取文件类型,则读取二进制流,对二进制进行解析文件类型var imgType = ['ff d8 ff', //jpg'89 50 4e', //png'0 0 0 14 66 74 79 70 69 73 6F 6D', //mp4'0 0 0 18 66 74 79 70 33 67 70 35', //mp4'0 0 0 0 66 74 79 70 33 67 70 35', //mp4'0 0 0 0 66 74 79 70 4D 53 4E 56', //mp4'0 0 0 0 66 74 79 70 69 73 6F 6D', //mp4'0 0 0 18 66 74 79 70 6D 70 34 32', //m4v'0 0 0 0 66 74 79 70 6D 70 34 32', //m4v'0 0 0 14 66 74 79 70 71 74 20 20', //mov'0 0 0 0 66 74 79 70 71 74 20 20', //mov'0 0 0 0 6D 6F 6F 76', //mov'4F 67 67 53 0 02', //ogg'1A 45 DF A3', //ogg'52 49 46 46 x x x x 41 56 49 20', //avi (RIFF fileSize fileType LIST)(52 49 46 46,DC 6C 57 09,41 56 49 20,4C 49 53 54)];var typeName = ['jpg','png','mp4','mp4','mp4','mp4','mp4','m4v','m4v','mov','mov','mov','ogg','ogg','avi',];var sliceSize = /png|jpg|jpeg/.test(type) ? 3 : 12;var reader = new FileReader();reader.readAsArrayBuffer(file);reader.addEventListener("load", function(e) {var slice = e.target.result.slice(0, sliceSize);reader = null;if (slice && slice.byteLength == sliceSize) {var view = new Uint8Array(slice);var arr = [];view.forEach(function(v) {arr.push(v.toString(16));});view = null;var idx = arr.join(' ').indexOf(imgType);if (idx > -1) {back(typeName[idx]);} else {arr = arr.map(function(v) {if (i > 3 && i < 8) {return 'x';}return v;});var idx = arr.join(' ').indexOf(imgType);if (idx > -1) {back(typeName[idx]);} else {back(false);}}} else {back(false);}});} else {var type = file.name.match(/\.(\w+)$/)[1];back(type);}
}

调用

checkFileType('(mov|mp4|avi)',file,function(fileType){// fileType = mp4,// 如果file的类型不在枚举之列,则返回false
});

上面上传文件的一步,可以改成

formdata.append('filename', md5code+'.'+fileType);

有了切割上传后,也就有了文件唯一标识信息,断点续传变成了后台的一个小小的逻辑判断

后端主要做的内容为:根据前端传给后台的md5值,到服务器磁盘查找是否有之前未完成的文件合并信息(也就是未完成的半成品文件切片),取到之后根据上传切片的数量,返回数据告诉前端开始从第几节上传

如果想要暂停切片的上传,可以使用XMLHttpRequest的 abort方法

使用场景

  • 大文件加速上传:当文件大小超过预期大小时,使用分片上传可实现并行上传多个 部分, 以加快上传速度
  • 网络环境较差:建议使用分片上传。当出现上传失败的时候,仅需重传失败的部分
  • 流式上传:可以在需要上传的文件大小还不确定的情况下开始上传。这种场景在视频监控等行业应用中比较常见

小结

考虑到更多场景

  • 切片上传失败怎么办
  • 上传过程中刷新页面怎么办
  • 如何进行并行上传
  • 切片什么时候按数量切,什么时候按大小切
  • 如何结合 Web Worker 处理大文件上传
  • 如何实现秒传

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_326374.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mycat2 使用教程(三)原始数据导入分库分表【MySQL分库分库分表】

Mycat2 使用教程&#xff08;三&#xff09;原始数据导入分库分表【MySQL分库分库分表】 本文主要描述mycat2完成分库分别数据源配置后&#xff0c;将数据导入的过程mysql 分库分表如果是新项目&#xff0c;则不用考虑本文内容mycat2如何配置分库分表&#xff1f;见上文 1.计…

5个网站帮你找到免费优质的视频素材

5个免费可商用视频素材网站&#xff0c;建议收藏&#xff01; 潮点视频 https://shipin520.com/shipin-mb/all-def-267-all-all-all-all-all-0-1.html?from_code2510 潮点视频是一个提供优质高清、无水印的视频素材网站&#xff0c;站内有大量的AE模板、PR模板、实拍素材、视…

自定义 MVC 框架思想

目录 一、MVC设计模式 1. 什么是MVC 2. 三层架构与MVC的区别 二、自定义MVC框架 1. 为什么要学习自定义MVC框架 2. 自定义MVC的工作原理 3. 自定义MVC框架的优势 三、自定义MVC实例流程 1. mvc三层架构的弊端 2. 自定义MVC的工作流程 2.1 子控制器&#xff08;…

打包时未添加livepusher模块

我们的项目采用的是混入开发&#xff0c;html5, 使用到了安卓离线打包&#xff0c;其中使用到了livepusher模块&#xff0c;本来没什么难事的&#xff0c;很简单的一个问题&#xff0c;但是中文的官方文档却介绍错了包名&#xff0c;一直在郁闷为啥不行&#xff0c;痛苦啊。本来…

计算机基础--->数据结构(7)【红黑树】

文章目录 二三树二三树的性质二三树一个简单的插入例子二三树的特点 红黑树红黑树的特点红黑树的节点红黑树的插入操作1. 左旋2. 右旋颜色翻转3. 颜色翻转插入实例 二三树 二三树与红黑树的性质非常相似&#xff0c;但是二三树能更直观的让人理解构建过程 二三树的性质 二三树是…

skywalking linux安装部署

SkyWalking APM tar 下载 结合自己的es版本下载对应的tar 地址&#xff1a;https://archive.apache.org/dist/skywalking/ 由于我使用的是es7所以下载对应版本 拷贝对应链接使用wget下载 wget https://archive.apache.org/dist/skywalking/8.7.0/apache-skywalking-apm-es7…

信息安全概述笔记

保密性、完整性、可用性是传统的信息安全的原则和目标&#xff0c;目前随着信息安全问题的日益严峻&#xff0c;信息安全的原则和目标衍生为诸如可控性、不可否认性等其他的原则和目标。 保密性&#xff08;Confidentiality&#xff09;:确保信息只能由那些被授权使用的人获取…

【论文笔记】Skill-based Meta Reinforcement Learning

【论文笔记】Skill-based Meta Reinforcement Learning 文章目录 【论文笔记】Skill-based Meta Reinforcement LearningAbstract1 INTRODUCTION2 RELATED WORKMeta-Reinforcement LearningOffline datasetsOffline Meta-RLSkill-based Learning 3 PROBLEM FORMULATION AND PRE…

IDEA远程操作HDFS

IDEA远程管理HDFS 本地环境配置 Windows 解压到本地磁盘 配置环境变量 添加winutils.exe和hadoop.dll Hadoop本身对Windows的支持并不友好&#xff0c;如果需要完整使用&#xff0c;需要将winutils.exe和hadoop.dll两个文件移动到%HADOOP_HOME%\bin目录 修改hadoop-e…

MySQL的存储引擎与基本使用讲解

目录 一、前言 1.MySQL的介绍 二、存储引擎 1.什么是存储引擎 2.常见存储引擎 2.1.InnoDB(MySQL默认引擎) 2.1.1.四种隔离级别 2.2.MyISAM存储引擎 2.3.Memory存储引擎 3.ACID事务 三、CRUD操作 1.插入数据 2.查询数据 3.修改数据 4.删除数据 四、数据库 1.默认…

小白开酒吧前要知道的几个知识(四)

第七、岗位分工 酒吧一定要分工明确&#xff0c;各司其职。每一个岗位都有着自己的职责&#xff0c;每一个环节都有所关联&#xff0c;每天上班前需要提前安排好各岗位的工作。团队需要一个规章制度&#xff0c;毕竟没有规矩不成方圆&#xff0c;建立岗位相关的工作制度以及责…

html---链接跳转案例

目录 一、要求&#xff1a;设置一个网页如下图所示&#xff0c;可实现首页、列表页、详情页、登录页链接 二、实现&#xff1a;实现代码及截图如下 三、寄语 一、要求&#xff1a;设置一个网页如下图所示&#xff0c;可实现首页、列表页、详情页、登录页链接 二、实现&…

弃购邮件:用这一招帮您赢回失去的客户

弃购邮件&#xff1a;用这一招帮您赢回失去的客户 弃购邮件是发送给将产品添加至购物车却没有结算的顾客&#xff08;即弃单顾客&#xff09;的邮件。 这是一种十分有效的顾客留存策略。 在线客户放弃购物车的频率比您想象的要高。他们没有完成购买的原因有很多。但是&#xff…

创作神器:探索ai智能绘画软件的魅力与功能

曾经有一个名叫小艾的年轻画家&#xff0c;她对绘画充满热情&#xff0c;并梦想创作出令人惊叹的艺术作品。然而&#xff0c;她发现自己在技术和创意方面遇到了一些困难。正当她感到沮丧时&#xff0c;她听说了一个关于智能ai绘画软件的故事&#xff0c;这个软件据说能够通过机…

Springboot整合Activiti详解

文章目录 版本依赖配置文件需要注意的问题画流程图activiti服务类进行编写流程部署流程定义启动流程流程实例 测试流程启动流程完成任务受理任务 版本依赖 开发工具 IDEASpringBoot 2.4.5&#xff08;这里我试过SpringBoot 3.1.1版本&#xff0c;Activiti没有启动&#xff0c;…

测试开发 —— 快速定位问题

写在前面 这两天工作实在是有点小忙&#xff0c;感觉好久没更新了&#xff0c;但是平时也是有感而发的比较多&#xff0c;今天遇到一个问题&#xff0c;感觉挺有意思&#xff0c;处理过程也非常有意义&#xff0c;希望能给大家一个借鉴吧。 测试平台又又又出问题了 今天一位…

一招教你看懂KMP算法next数组

给两个字符串&#xff0c;一个匹配串&#xff0c;一个主串&#xff0c;我们要在主串中找到第一个匹配串&#xff0c;并全部返回 eg: p"aba"; s"bbabaca"; 那么返回的就是第一个找到的匹配串的下标 返回2; 这里最容易想到的就是暴力匹配了,挨个&#xff0c;…

云原生(第四篇)-k8s yaml文件

Kubernetes 支持 YAML 和 JSON 格式管理资源对象 JSON 格式&#xff1a;主要用于 api 接口之间消息的传递 YAML 格式&#xff1a;用于配置和管理&#xff0c;YAML 是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读 YAML 语法格式&#xff1a; ●大小写敏…

还在用策略模式解决 if-else?Map+函数式接口方法才是YYDS!

本文介绍策略模式的具体应用以及Map函数式接口如何 “更完美” 的解决 if-else的问题。 需求 最近写了一个服务&#xff1a;根据优惠券的类型resourceType和编码resourceId来 查询 发放方式grantType和领取规则 实现方式&#xff1a; 根据优惠券类型resourceType -> 确定查…