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

文件上传之大文件分块上传

分久必合,合久必分

优势部分:减少了内存占用,可实现断点续传,并发处理,利用带宽,提高效率
不足之处:增加复杂性,增加额外计算存储
应用场景:云存储大文件上传、多媒体平台音视频上传,需断点续传应用
注意事项::理分块大小,顺序的完整性,异常情况的合理处理

示例:

前端:

<input type="file" id="fileInput"/>
<button onClick={upload()}>上传文件
</button>
<script>async function upload(){const fileInput = document.getElementById('fileInput');const file = fileInput.files[0];const chunkSize = 1 * 1024 * 1024; // 设置每个分片的大小为1MBconst totalChunks = Math.ceil(file.size / chunkSize); // 计算文件总分片数let currentChunk = 0; // 当前处理的分片索引while (currentChunk < totalChunks) {const start = currentChunk * chunkSize; //计算当前块的起始位置const end = Math.min(start + chunkSize, file.size); //计算当前块的结束位置const chunk = file.slice(start, end);  //切割文件为当前块const formData = new FormData();formData.append('file', chunk); //添加当前块到FormData对象formData.append('filename', file.name); //添加文件名到FormData对象formData.append('totalChunks', totalChunks); //添加总块数到FormData对象formData.append('currentChunk', currentChunk); //添加当前块数到FormData对象try{await axios.post('http://localhost:3000/upload',formData,{headers:{'Content-Type':'multipart/form-data',},}); //发送当前块的上传请求}catch(error){console.error(error);return;}currentChunk++; //增加当前块数,继续下一块的上传}try{const postData = { filename:file.name,totalChunks:totalChunks }; //构造合并请求的数据await http.post('http://localhost:3000/merge', postData,{headers: {'Content-Type': 'application/json'}}); //发送合并请求}catch(error){console.error(error);}}
</script>

写完之后执行,就会看到,当我们进行上传时,会不断的像服务器发送请求

后端: 

后端使用:path解决路径问题  fs文件的读写操作  引入第三方类库multer进行文件上传的操作处理 设置一个上传地址upload   bodyParser利用它来实现body的解析操作

const express = require('express');
const cors = require('cors');
const path = require('path');
const fs = require('fs');
const multer = require('multer');
const upload = multer({dest:'uploads/'});
const bodyParser = require('body-parser');
const app = express();app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));app.post('/upload',(req,res) => {});app.listen(3000,() => {console.log('Server started on port 3000');
});

上传upload接口:

app.post('/upload',upload.single('file'),(req,res) => {const file = req.file; // 获取上传的文件对象const filename = req.body.filename; // 获取文件名const totalChunks = parseInt(req.body.totalChunks); // 获取总块数const currentChunk = parseInt(req.body.currentChunk); //获取当前块数const chunkPath = path.join("uploads/",`${filename}-chunk-${currentChunk}`); //生成当前存储路径const chunkStream = fs.createReadStream(file.path); //创建读取文件块的可读流const writeStream = fs.createWriteStream(chunkPath); //创建写入当前块的可写流chunkStream.pipe(writeStream); //将读取的文件块内容通过管道写入当前块的文件chunkStream.on("end", () => {fs.unlinkSync(file.path); //读取文件块的流结束后,删除临时文件res.sendStatus(200); //响应上传成功的状态});
});

切片传递完毕之后,我们要进行merge合并的一个请求操作。

merge合并接口:

router.post("/merge", (req, res) => {const filename = req.body.filename; //获取文件名const totalChunks = parseInt(req.body.totalChunks);  //获取总块数const mergedPath = path.join("uploads", filename); //生成合并后文件的存储路径const writeStream = fs.createWriteStream(mergedPath); //创建写入合并后文件的可写流const mergeChunks = (index) => {if (index === totalChunks) {writeStream.end(); //所有块都合并完成后,关闭写入流res.sendStatus(200); //响应合并成功的状态return;}const chunkPath = path.join("uploads", `${filename}-chunk-${index}`); //获取当前块的存储路径const chunk = fs.readFileSync(chunkPath); //同步读取当前块的内容fs.unlinkSync(chunkPath); //删除已合并的块文件writeStream.write(chunk,() => {mergeChunks(index + 1); //递归合并下一块});};mergeChunks(0); //从第一块开始合并
});

那么这时当我上传文件时,我们可以看到有大量的视频文件,当请求完毕后,会合并成一个文件

那么此时我们就已经实现了大文件上传的效果,利用分久必合,合久必分原则,前端进行了块级的分割,像服务器端不断的发送块级文件内容,以便实现服务器端的分久必合操作。操作之后,执行merge请求,利用merge对分久必合以后的内容进行请求操作,最终形成的是一个完整的上传文件的内容。

以上就是此内容,希望对您有所帮助。

相关文章:

文件上传之大文件分块上传

分久必合&#xff0c;合久必分 优势部分&#xff1a;减少了内存占用&#xff0c;可实现断点续传&#xff0c;并发处理&#xff0c;利用带宽&#xff0c;提高效率 不足之处&#xff1a;增加复杂性&#xff0c;增加额外计算存储 应用场景&#xff1a;云存储大文件上传、多媒体平台…...

测试用例评审流程

1:评审的过程 A:开始前做好如下准备 1、确定需要评审的原因 2、确定进行评审的时机 3、确定参与评审人员 4、明确评审的内容 5、确定评审结束标准 6、提前至少一天将需要评审的内容以邮件的形式发送给评审会议相关人员。并注明详审时间、地点及偿参与人员等。 7、 在邮件中提醒…...

鸿蒙开发案列一

1、开发需求 案例app一打开是“Hello world” 界面&#xff0c;开发者点击“Hello world”变成“Hello ArkUI”’ 2、源代码 Entry Component struct Hello {State person_name: string Worldbuild() {Row() {Column() {Text(Hello this.person_name).fontSize(50).fontWei…...

Vue实现图片预览,侧边栏懒加载,不用任何插件,简单好用

实现样式 需求 实现PDF上传预览&#xff0c;并且不能下载 第一次实现&#xff1a;用vue-pdf&#xff0c;将上传的文件用base64传给前端展示 问题&#xff1a; 水印第一次加载有后面又没有了。当上传大的pdf文件后&#xff0c;前端获取和渲染又长又慢&#xff0c;甚至不能用 修…...

Spring依赖注入之setter注入与构造器注入以及applicationContext.xml配置文件特殊值处理

依赖注入之setter注入 在管理bean对象的组件的时候同时给他赋值&#xff0c;就是setter注入&#xff0c;通过setter注入&#xff0c;可以将某些依赖项标记为可选的&#xff0c;因为它们不是在构造对象时立即需要的。这种方式可以减少构造函数的参数数量&#xff0c;使得类的构…...

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测,预测新数据

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测&#xff0c;预测新数据 目录 碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测&#xff0c;预测新数据预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现LSTM长短期记忆神经网络多输入单输出未来…...

手拉手JavaFX UI控件与springboot3+FX桌面开发

目录 javaFx文本 javaFX颜色 字体 Label标签 Button按钮 //按钮单击事件 鼠标、键盘事件 //(鼠标)双击事件 //键盘事件 单选按钮RadioButton 快捷键、键盘事件 CheckBox复选框 ChoiceBox选择框 Text文本 TextField(输入框)、TextArea文本域 //过滤 (传入一个参数&a…...

02 分解质因子

一、数n的质因子分解 题目描述&#xff1a; 输入一个数n&#xff08;n<10^6&#xff09;,将数n分解质因数&#xff0c;并按照质因数从小到大的顺序输出每个质因数的底数和指数。 输入 5 输出 5 1 输入 10 输出 2 1 5 1 朴素解法&#xff1a; 首先求出1~n的所有质数…...

科技赋能智慧水利——山海鲸软件水利方案解析

作为山海鲸可视化软件的开发者&#xff0c;我们深感荣幸能为我国智慧水利建设提供强大助力。作为钻研数字孪生领域的开创者&#xff0c;我们希望不仅能为大家带来免费好用&#xff0c;人人都能用起来的数字孪生产品&#xff0c;还希望以其独特的技术优势和创新设计理念&#xf…...

C4.5决策树的基本建模流程

C4.5决策树的基本建模流程 作为ID3算法的升级版&#xff0c;C4.5在三个方面对ID3进行了优化&#xff1a; &#xff08;1&#xff09;它引入了信息值&#xff08;information value&#xff09;的概念来修正信息熵的计算结果&#xff0c;以抑制ID3更偏向于选择具有更多分类水平…...

本科毕业设计过程中应该锻炼的能力 (深度学习方向)

摘要: 本文以本科毕业设计做深度学习方向, 特别是全波形反演为例, 描述学生应在此过程中锻炼的能力. 搭建环境的能力. 包括 Python, PyTorch 等环境的安装.采集数据的能力. 包括 OpenFWI 等数据集.查阅资料的能力. 包括自己主要参考的文献, 以及其它相关文献 (不少于 20 篇). …...

深度学习——pycharm远程连接

目录 远程环境配置本地环境配置&#xff08;注意看假设&#xff01;&#xff01;!这是很多博客里没写的&#xff09;步骤1步骤2步骤2.1 配置Connection步骤2.2 配置Mappings 步骤3 配置本地项目的远程解释器技巧1 pycharm中远程终端连接技巧2 远程目录技巧3 上传代码文件技巧4 …...

信号量机制解决经典同步互斥问题

生产者 / 消费者问题、读者 / 写者问题和哲学家问题是操作系统的三大经典同步互斥问题。本文将介绍这三个问题的基本特点以及如何用信号量机制进行解决。 在分析这三个问题之前&#xff0c;我们首先需要了解用信号量机制解决同步互斥问题的一般规律&#xff1a; 实现同步与互斥…...

java基础09-==和equals()的区别,附代码举例

和equals()的区别 在Java中&#xff0c;和equals()是两个不同的运算符&#xff0c;它们在比较对象时有着本质的区别。 运算符: 用于比较两个基本数据类型&#xff08;如int、char等&#xff09;或两个对象的引用。 当用于比较基本数据类型时&#xff0c;它会比较它们的值。 当…...

qml与C++的交互

qml端使用C对象类型、qml端调用C函数/c端调用qml端函数、qml端发信号-连接C端槽函数、C端发信号-连接qml端函数等。 代码资源下载&#xff1a; https://download.csdn.net/download/TianYanRen111/88779433 若无法下载&#xff0c;直接拷贝以下代码测试即可。 main.cpp #incl…...

LabVIEW电路板插件焊点自动检测系统

LabVIEW电路板插件焊点自动检测系统 介绍了电路板插件焊点的自动检测装置设计。项目的核心是使用LabVIEW软件&#xff0c;开发出一个能够自动检测电路板上桥接、虚焊、漏焊和多锡等焊点缺陷的系统。 系统包括成像单元、机械传动单元和软件处理单元。首先&#xff0c;利用工业相…...

第十一站:多态练习ODU

实现动态切换 ODU.h #pragma once #include <iostream> using namespace std; #define ODU_TYPE_311_FLAG "311" #define ODU_TYPE_335_FLAG "335" enum class ODU_TYPE {ODU_TYPE_311,ODU_TYPE_335,ODU_TYPE_UNKNOW };class ODU{ public:ODU();//发…...

【深度学习】详解利用Matlab和Python中 LSTM 网络实现序列分类

🔗 运行环境:Matlab、Python 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 🔐#### 防伪水印——左手の明天 ####🔐 💗 大家好🤗🤗🤗,我是左手の明天!好久不见💗 💗今天分享Matlab深度学习—— LSTM 网络实现序列分...

Unity 工厂方法模式(实例详解)

文章目录 在Unity中&#xff0c;工厂方法模式是一种创建对象的常用设计模式&#xff0c;它提供了一个接口用于创建对象&#xff0c;而具体的产品类是由子类决定的。这样可以将对象的创建过程与使用过程解耦&#xff0c;使得代码更加灵活和可扩展。 工厂模式的主要优点如下&…...

2024年美赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...