当前位置: 首页 > news >正文

大文件上传如何做断点续传?

在这里插入图片描述


文章目录

  • 一、是什么
    • 分片上传
    • 断点续传
  • 二、实现思路
  • 三、使用场景
    • 小结
  • 参考文献


一、是什么

不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂

文件上传简单,文件变大就复杂

上传大文件时,以下几个变量会影响我们的用户体验

  • 服务器处理数据的能力
  • 请求超时
  • 网络波动

上传时间会变长,高频次文件上传失败,失败后又需要重新上传等等

为了解决上述问题,我们需要对大文件上传单独处理

这里涉及到分片上传及断点续传两个概念

分片上传

分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(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值,到服务器磁盘查找是否有之前未完成的文件合并信息(也就是未完成的半成品文件切片),取到之后根据上传切片的数量,返回数据告诉前端开始从第几节上传

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


三、使用场景

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

小结

当前的伪代码,只是提供一个简单的思路,想要把事情做到极致,我们还需要考虑到更多场景,比如

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

人生又何尝不是如此,极致的人生体验有无限可能,越是后面才发现越是精彩 _


参考文献

  • https://segmentfault.com/a/1190000009448892
  • https://baike.baidu.com/

希望本文能够对您有所帮助!如果您有任何问题或建议,请随时在评论区留言联系 章挨踢(章IT)
谢谢阅读!

相关文章:

大文件上传如何做断点续传?

文章目录 一、是什么分片上传断点续传 二、实现思路三、使用场景小结 参考文献 一、是什么 不管怎样简单的需求&#xff0c;在量级达到一定层次时&#xff0c;都会变得异常复杂 文件上传简单&#xff0c;文件变大就复杂 上传大文件时&#xff0c;以下几个变量会影响我们的用…...

SpringCloud-Eureka原理分析

Eureka是Netflix开源的一款用于实现服务注册与发现的工具。在微服务架构中&#xff0c;服务的动态注册和发现是必不可少的组成部分&#xff0c;而Eureka正是为了解决这一问题而诞生的。 一、为何需要Eureka 在微服务架构中&#xff0c;服务之间的协同合作和高效通信是至关重要…...

LeetCode周赛——384

1.修改矩阵&#xff08;模拟&#xff09; class Solution { public:vector<vector<int>> modifiedMatrix(vector<vector<int>>& matrix) {int n matrix.size();int m matrix[0].size();vector<int> ans(m);for(int i 0; i < m; i)for(…...

C#,巴都万数列(Padonve Number)的算法与源代码

1 巴都万数列&#xff08;Padovan Sequence&#xff09; 巴都万数列&#xff08;Padovan Sequence&#xff09;是一个整数数列。 首数个值为1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37 ... 此数列以建筑师理察巴都万命名&#xff0c;他的论文Dom&#xff08;1994年&a…...

NSSCTF Round#18 RE GenshinWishSimulator WP

恶搞原神抽卡模拟器 看到软件的界面&#xff0c;大致有三种思路&#xff1a; 修改石头数量一直抽&#xff0c;如果概率正常肯定能抽到&#xff08;但是估计设置的概率是0&#xff09;在源码里找flag的数据把抽卡概率改成100%直接抽出来 Unity逆向&#xff0c;根据经验应该dnsp…...

鸿蒙系统对应安卓版本

鸿蒙系统对应安卓版本 使用安卓studio 新建一个app 然后添加代码打印&#xff1a; Log.d(“MainActivity”, "SDK Version: " Build.VERSION.SDK_INT); 或者把 Build.VERSION.SDK_INT 添加到显示的字符串上面 我这里 build.gradle.kts 配置 android {compileSdk…...

算法-16-并查集

并查集简介 并查集&#xff1a;一开始&#xff0c;把a&#xff0c;b&#xff0c;c放入并查集&#xff0c;a自己一个集合&#xff0c;b自己一个&#xff0c;c自己一个 提供的方法 1.boolean isSameSet(a,b)&#xff0c;判断ab是否在同一个集合 2.void union(a,b),把a所…...

【C/C++】2024春晚刘谦春晚魔术步骤模拟+暴力破解

在这个特别的除夕夜&#xff0c;我们不仅享受了与家人的温馨团聚&#xff0c;还被电视机前的春节联欢晚会深深吸引。特别是&#xff0c;魔术师刘谦的精彩表演&#xff0c;为我们带来了一场视觉和心灵的盛宴。在我的博客“【C/C】2024春晚刘谦春晚魔术步骤模拟暴力破解”中&…...

Java运算符和表达式

Java运算符和表达式 和C语言一样&#xff0c;java也有基础的运算符和表达式&#xff0c;用来完成一些基础的数学计算&#xff0c;以及逻辑运算&#xff0c;我们一起来学习一下吧。 算数运算符 首先&#xff0c;这个算数运算符与数学中即C语言的运算符的功能一样&#xff0c;利…...

波奇学Linux:软硬链接

ln指令建立链接 软链接 硬链接 所属者的前的数字表示硬链接数&#xff0c;引用计数&#xff0c;file.txt和soft_link是软链接所以都为2 软链接有独立inode&#xff0c;硬链接没有&#xff0c;所以硬链接不是独立文件&#xff0c;软链接是独立文件&#xff0c;且硬链接的属性会…...

HTTP网络通信协议基础

目录 前言&#xff1a; 1.HTTP协议理论 1.1协议概念 1.2工作原理 1.3工作场景 2.HTTP抓包工具 2.1Fiddler工具 2.2抓包原理 2.3抓包结果 3.HTTP协议格式 3.1HTTP请求 3.2HTTP响应 3.3格式总结 前言&#xff1a; 在了解完网络编程的传输层UDP和TCP通信协议后&#…...

Java实现河南软件客服系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、系统展示四、核心代码4.1 查询客户4.2 新增客户跟进情况4.3 查询客户历史4.4 新增服务派单4.5 新增客户服务费 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的河…...

【小沐学GIS】基于C++QT绘制三维数字地球Earth(OpenGL)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第二期3【小沐…...

如何生成生成一个修仙世界的狗血短剧剧本

如何生成生成一个修仙世界的狗血短剧剧本 生成一个修仙世界的狗血短剧剧本将上述剧本转为对话 生成一个修仙世界的狗血短剧剧本 剧本名称&#xff1a;《仙途情缘》 角色&#xff1a; 易天行&#xff1a;男主角&#xff0c;天赋异禀的修仙者&#xff0c;性格坚毅&#xff0c;正…...

【MIMO】

MIMO技术入门 1.简介 MIMO(多入多出):多天线技术。 注意&#xff1a;此处的多天线&#xff0c;并不是有多个天线板&#xff0c;对基站来讲指天线有多套振子&#xff08;每一套振子都可以看成一个独立的天线&#xff09;。 4G 8天线&#xff1b;5G 64T64R&#xff1b;不仅基站…...

ZooKeeper分布式锁

ZooKeeper是一个开源的分布式协调服务&#xff0c;它主要用于维护配置信息、提供分布式同步、命名服务等。ZooKeeper的数据模型类似于文件系统&#xff0c;它的数据结构中的每个数据节点称为znode&#xff0c;可以用它来实现分布式锁。 ZooKeeper分布式锁的原理&#xff1a; …...

WPF是不是垂垂老矣啦?平替它的框架还有哪些

WPF&#xff08;Windows Presentation Foundation&#xff09;是微软推出的一种用于创建 Windows 应用程序的用户界面框架。WPF最初是在2006年11月推出的&#xff0c;它是.NET Framework 3.0的一部分&#xff0c;为开发人员提供了一种基于 XAML 的方式来构建丰富的用户界面。 W…...

浅析Linux追踪技术之ftrace:Tracepoint

文章目录 概述Tracepoint使用定义Tracepoint添加Tracepoint调用 Tracepoint数据结构TRACE_EVENT实现DECLARE_TRACE__DECLARE_TRACE trace_xxx函数相关参考 概述 Tracepoint&#xff08;跟踪点&#xff09;是添加到代码流程中的调用点&#xff0c;并且允许开发者注册自定义的回…...

python ftp文件断点续传 并判断ftp文件下载完成

在Python中实现FTP文件的断点续传&#xff0c;通常涉及到以下步骤&#xff1a; 连接到FTP服务器。获取远程文件的大小。检查本地文件是否存在以及它的大小。如果本地文件不存在或大小小于远程文件&#xff0c;从上次中断的位置开始下载。下载完成后&#xff0c;检查文件大小以…...

SpringBoot+Vue3 完成小红书项目

简介 该项目采用微服务架构&#xff0c;实现了前后端分离的系统设计。在前端&#xff0c;我们选择了 Vue3 配合 TypeScript 和 ElementUi 框架&#xff0c;以提升开发效率和用户体验。而在后端&#xff0c;则是运用 SpringBoot 和 Mybatis-plus 进行开发&#xff0c;保证了系统…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...