文件分块+断点续传 实现大文件上传全栈解决方案(前端+nodejs)

ops/2024/10/18 23:26:05/

1. 文件分块

将大文件切分成较小的片段(通常称为分片或块),然后逐个上传这些分片。这种方法可以提高上传的稳定性,因为如果某个分片上传失败,只需要重新上传该分片而不需要重新上传整个文件。同时,分片上传还可以利用多个网络连接并行上传多个分片,提高上传速度。

2. 断点续传

在上传过程中,如果网络中断或上传被中止,断点续传技术可以记录已成功上传的分片信息,以便在恢复上传时继续上传未完成的部分,而不需要重新上传整个文件。这种技术可以大大减少上传失败的影响,并节省时间和带宽。

3. node项目目录初始化

在这里插入图片描述

  1. 安装依赖

    • express 敏捷启动服务
    • multer 读取文件,存储
    • cors 解决跨域
  2. 目录结构

    • src
      • TED.mp4 (长视频,10分钟,可以下载这个 https://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4
    • uploads 存放切片
    • video 存放将切片拼接后的视频
    • index.html 前端页面

代码附上

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><input id="file" type="file" /><script>// functions// 实现切片的方法const makeChunk = (file, size = 1024 * 1024 * 4) => {const chunks = [];for (let i = 0; i < file.size; i += size) {const chunk = file.slice(i, i + size);chunks.push(chunk);}return chunks;};// 上传分片后的文件方法const uploadChunks = (chunks) => {// 1. 使用Promise.all保证所有上传方法执行成功// 2. 必须要给每个分片文件加标识,才可以让node端进行按序拼接const list = [];for (let i = 0; i < chunks.length; i++) {const formData = new FormData();formData.append("filename", "ted");formData.append("index", i);formData.append("chunk", chunks[i]); // 千万注意,切片文件要最后append否则会出现意外的buglist.push(fetch("http://localhost:3000/upload", {method: "POST",body: formData,}));}Promise.all(list).then((res) => {console.log("上传成功", res);fetch("http://localhost:3000/merge", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({fileName: "TED演讲10分钟长视频",}),});}).catch((err) => {console.error("上传失败", err);});};// logicconst file = document.querySelector("#file");file.addEventListener("change", (e) => {let file = e.target.files[0]; // 我们只处理单个文件因此取第一个元素即可// file是一个对象,底层继承于Blob,借助于Blob身上的slice方法,可以实现对大文件的分片操作console.log(file);const chunks = makeChunk(file);console.log("chunks:", chunks);uploadChunks(chunks);});</script></body>
</html>

index.js

import fs from "node:fs";
import path from "node:path";
import express from "express";
import multer from "multer";
import cors from "cors";console.log("cors:", cors);// 1. 初始化multer
const storage = multer.diskStorage({// 指定切片存放目录destination: function (req, file, cb) {cb(null, "../uploads/");},filename: function (req, file, cb) {console.log("req.body.index:", req.body.index);console.log("file", file);cb(null, `${req.body.filename}-${req.body.index}`);},
});const upload = multer({ storage });const app = express();
app.use(cors());
app.use(express.json());// upload.single("chunk") 其中chunk对应前端上传的文件切片名字
app.post("/upload", upload.single("chunk"), (req, res) => {console.log("req.body:", req.body);res.header("Content-Type", "application/json;charset=utf-8");res.send("ok");
});// 拼接切片
app.post("/merge", (req, res) => {// 获取uploadDir的目录const uploadDir = path.join(process.cwd(), "../uploads");const dirs = fs.readdirSync(uploadDir); // 发现是乱序的// 对dirs数组进行排序dirs.sort((a, b) => {return a.split("-")[1] - b.split("-")[1];});const videoDir = path.join(process.cwd(),"../video",`${req.body.fileName}.mp4`);dirs.forEach((item) => {// 合并成一个完整的文件至video目录fs.appendFileSync(videoDir, fs.readFileSync(path.join(uploadDir, item)));// 删除已合并的切片文件fs.unlinkSync(path.join(uploadDir, item));});console.log(dirs);res.send("okk");
});app.listen(3000, () => {console.log("server is running at port 3000");
});

最终效果

在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/ops/25678.html

相关文章

JSON和Python内置的数据类型对应关系

Json JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它基于ECMAScript的一个子集&#xff0c;采用完全独立于语言的文本格式来存储和表示数据。Python则是一种解释型、面向对象、动态数据类型的高级程序设计语言。在Python中&…

TinyMaix在x210开发板上的移植

目录 说明 环境准备 编译代码 源程序下载 修改tm_port.文件 修改CMake文件 测试程序运行 说明 我们教学中使用的x210开发板使用S5PV210这款CPU&#xff0c;它是根据三星的smdkv210开发板进行裁剪设计的&#xff0c;这个开发板非常的老了&#xff0c;不过在有经费购买新…

Linux基础——Linux开发工具(上)_vim

前言&#xff1a;在了解完Linux基本指令和Linux权限后&#xff0c;我们有了足够了能力来学习后面的内容&#xff0c;但是在真正进入Linux之前&#xff0c;我们还得要学会使用Linux中的几个开发工具。而我们主要介绍的是以下几个&#xff1a; yum, vim, gcc / g, gdb, make / ma…

树莓派5用docker运行Ollama3

书接上回&#xff0c;树莓派5使用1panel安装 Ollama 点击终端就可以进入容器 输入以下代码 ollama run llama3Llama3 是市场推崇的版本。您的 树莓派5上必须至少有 4.7GB 的可用空间&#xff0c;因此用树莓派玩机器学习就必须配置大容量的固态硬盘。用1panel部署网络下载速度…

LinkedList与链表

文章目录 ArrayList的缺陷链表链表的概念及结构链表的实现 LinkedList的使用什么是LinkedListLinkedList具体使用 ArrayList和LinkedList的区别 ArrayList的缺陷 通过源码知道&#xff0c;ArrayList底层使用数组来存储元素 由于其底层是一段连续空间&#xff0c;当在ArrayList任…

【MySQL】A01、性能优化-参数监控分析

1、参数监控 1.1、MySQL command 查看 mysql>SHOW STATUS; &#xff08;服务器状态变量&#xff0c;运行服务器的统计和状态指标&#xff09; mysql> SHOW VARIABLES;&#xff08;服务器系统变量&#xff0c;实际上使用的变量的值&#xff09; mysql> SHOW STATUS …

数据结构––复杂度

目录 一.时间复杂度 1.1定义 1.2时间复杂度的分类 1.3时间复杂度基本计算规则 1.4例子 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.4.10 1.4.11 1.4.12 1.4.13 二.空间复杂度 2.1定义 2.2推导大O阶方法 一.时间复杂度 1.1定义 算法的时间…

flutter笔记-hello dart

文章目录 1. 搭建环境2. 运行官方首个程序3. AS中运行iOSAndroid 语法简述1. 变量常量字符串补充 2. 集合3. 函数关于可选报错&#xff1a;匿名函数 4. 特殊运算符5. 类 dart 包 1. 搭建环境 环境的搭建在window和mac都差不多&#xff0c;都是从官网下载对应操作系统对应版本的…