大文件上传之断点续传实现方案与原理详解

一、实现原理

文件分块:将大文件切割为固定大小的块(如5MB)
进度记录:持久化存储已上传分块信息
续传能力:上传中断后根据记录继续上传未完成块
块校验机制:通过哈希值验证块完整性
合并策略:所有块上传完成后进行有序合并

二、前端实现(JavaScript)

// 文件分块(示例使用Blob.slice)
// 默认 5M 一个片段
function createChunks(file, chunkSize = 5 * 1024 * 1024) {const chunks = [];let offset = 0;while (offset < file.size) {const chunk = file.slice(offset, offset + chunkSize);chunks.push({chunk,index: chunks.length,hash: file.name + '-' + chunks.length});offset += chunkSize;}return chunks;
}// 上传控制器
class Uploader {constructor(file) {this.file = filethis.chunks = createChunks(file)this.uploaded = new Set() // 已上传分块索引}async checkProgress() {// 查询服务端已上传分块const { data } = await axios.get('/progress', {params: { hash: this.fileHash }})this.uploaded = new Set(data.uploaded)}async upload() {await this.checkProgress()for (const chunk of this.chunks) {if (this.uploaded.has(chunk.index)) continueconst formData = new FormData()formData.append('chunk', chunk.chunk)formData.append('hash', chunk.hash)formData.append('index', chunk.index)formData.append('total', this.chunks.length)await axios.post('/upload', formData, {onUploadProgress: progress => {console.log(`${chunk.index}上传进度:`, progress)}})this.uploaded.add(chunk.index)}await axios.post('/merge', { filename: this.file.name,total: this.chunks.length })}
}

三、服务端实现(Node.js + Express

const express = require('express')
const fs = require('fs-extra')
const path = require('path')
const app = express()// 临时存储目录
const UPLOAD_DIR = path.resolve(__dirname, 'temp')// 处理分块上传
app.post('/upload', async (req, res) => {const { chunk, hash, index } = req.filesconst chunkDir = path.resolve(UPLOAD_DIR, hash.split('-')[0])await fs.ensureDir(chunkDir)await fs.move(chunk.path, path.resolve(chunkDir, hash))res.json({ code: 0 })
})// 合并分块
app.post('/merge', async (req, res) => {const { filename, total } = req.bodyconst fileHash = filename + '-' + Date.now()const chunkDir = path.resolve(UPLOAD_DIR, fileHash)const destFile = path.resolve(UPLOAD_DIR, filename)// 按索引顺序合并await fs.ensureDir(chunkDir)for (let i = 0; i < total; i++) {const chunkPath = path.resolve(chunkDir, `${fileHash}-${i}`)await fs.appendFile(destFile, await fs.readFile(chunkPath))await fs.unlink(chunkPath)}await fs.rmdir(chunkDir)res.json({ code: 0 })
})// 查询上传进度
app.get('/progress', async (req, res) => {const { hash } = req.queryconst chunkDir = path.resolve(UPLOAD_DIR, hash.split('-')[0])if (!await fs.pathExists(chunkDir)) {return res.json({ uploaded: [] })}const uploaded = (await fs.readdir(chunkDir)).map(name => parseInt(name.split('-').pop()))res.json({ uploaded })
})

四、关键实现步骤

分块生成:前端使用Blob.slice进行文件切割
唯一标识:使用"文件名+哈希值"生成文件唯一标识

断点记录
服务端保存每个文件的分块目录
使用Set结构记录已上传分块索引

恢复机制
上传前先查询服务端上传进度
跳过已上传成功的分块

合并验证
按索引顺序合并保证文件正确性
合并完成后清理临时分块

五、注意事项

哈希校验:对每个分块计算MD5进行完整性验证
并发控制:前端使用Promise.all实现并行上传
错误重试:为每个分块添加重试机制
秒传功能:通过文件哈希值检测服务端已存在文件
分块大小自适应:根据网络状况动态调整分块尺寸

该方案,支持TB级文件上传,通过分块策略断点记录机制可显著提升大文件传输的可靠性。
实际部署时建议结合对象存储服务实现,可进一步降低服务器存储压力。

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

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

相关文章

【动手学深度学习】卷积神经网络(CNN)入门

【动手学深度学习】卷积神经网络&#xff08;CNN&#xff09;入门 1&#xff0c;卷积神经网络简介2&#xff0c;卷积层2.1&#xff0c;互相关运算原理2.2&#xff0c;互相关运算实现2.3&#xff0c;实现卷积层 3&#xff0c;卷积层的简单应用&#xff1a;边缘检测3.1&#xff0…

Opencv计算机视觉编程攻略-第十一节 三维重建

此处重点讨论在特定条件下&#xff0c;重建场景的三维结构和相机的三维姿态的一些应用实现。下面是完整投影公式最通用的表示方式。 在上述公式中&#xff0c;可以了解到&#xff0c;真实物体转为平面之后&#xff0c;s系数丢失了&#xff0c;因而无法会的三维坐标&#xff0c;…

大厂不再招测试?软件测试左移开发合理吗?

&#x1f449;目录 1 软件测试发展史 2 测试左移&#xff08;Testing shift left&#xff09; 3 测试右移&#xff08;Testing shift right&#xff09; 4 自动化测试 VS 测试自动化 5 来自 EX 测试的寄语 最近两年&#xff0c;互联网大厂的招聘中&#xff0c;测试工程师岗位似…

windows10下PointNet官方代码Pytorch实现

PointNet模型运行 1.下载源码并安装环境 GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/gh_mirrors/po/pointnet.pyto…

git pull 和 git fetch

关于 git pull 和 git fetch 的区别 1. git fetch 作用&#xff1a;从远程仓库获取最新的分支信息和提交记录&#xff0c;但不会自动合并或修改当前工作目录中的内容。特点&#xff1a; 它只是更新本地的远程分支引用&#xff08;例如 remotes/origin/suyuhan&#xff09;&am…

前端开发中的单引号(‘ ‘)、双引号( )和反引号( `)使用

前端开发中的单引号&#xff08;’ &#xff09;、双引号&#xff08;" "&#xff09;和反引号&#xff08; &#xff09;使用 在前端开发中&#xff0c;单引号&#xff08;’ &#xff09;、双引号&#xff08;" "&#xff09;和反引号&#xff08; &…

程序化广告行业(69/89):DMP与PCP系统核心功能剖析

程序化广告行业&#xff08;69/89&#xff09;&#xff1a;DMP与PCP系统核心功能剖析 在数字化营销浪潮中&#xff0c;程序化广告已成为企业精准触达目标受众的关键手段。作为行业探索者&#xff0c;我深知其中知识的繁杂与重要性。一直以来&#xff0c;都希望能和大家一同学习…

Amodal3R ,南洋理工推出的 3D 生成模型

Amodal3R 是一款先进的条件式 3D 生成模型&#xff0c;能够从部分可见的 2D 物体图像中推断并重建完整的 3D 结构与外观。该模型建立在基础的 3D 生成模型 TRELLIS 之上&#xff0c;通过引入掩码加权多头交叉注意力机制与遮挡感知注意力层&#xff0c;利用遮挡先验知识优化重建…

LLM面试题八

推荐算法工程师面试题 二分类的分类损失函数&#xff1f; 二分类的分类损失函数一般采用交叉熵(Cross Entropy)损失函数&#xff0c;即CE损失函数。二分类问题的CE损失函数可以写成&#xff1a;其中&#xff0c;y是真实标签&#xff0c;p是预测标签&#xff0c;取值为0或1。 …

30天学Java第7天——IO流

概述 基本概念 输入流&#xff1a;从硬盘到内存。&#xff08;输入又叫做 读 read&#xff09;输出流&#xff1a;从内存到硬盘。&#xff08;输出又叫做 写 write&#xff09;字节流&#xff1a;一次读取一个字节。适合非文本数据&#xff0c;它是万能的&#xff0c;啥都能读…

面试可能会遇到的问题回答(嵌入式软件开发部分)

写在前面&#xff1a; 博主也是刚入社会的小牛马&#xff0c;如果下面有写的不好或者写错的地方欢迎大家指出~ 一、四大件基础知识 1、计算机组成原理 &#xff08;1&#xff09;简单介绍一下中断是什么。 ①回答&#xff1a; ②难度系数&#xff1a;★★ ③难点分析&…

层归一化详解及在 Stable Diffusion 中的应用分析

在深度学习中&#xff0c;归一化&#xff08;Normalization&#xff09;技术被广泛用于提升模型训练的稳定性和收敛速度。本文将详细介绍几种常见的归一化方式&#xff0c;并重点分析它们在 Stable Diffusion 模型中的实际使用场景。 一、常见的归一化技术 名称归一化维度应用…

深入理解Socket编程:构建简单的计算器服务器

一、Socket通信基础 1. Socket通信基本流程 服务器端流程&#xff1a; 创建Socket (socket()) 绑定地址和端口 (bind()) 监听连接 (listen()) 接受连接 (accept()) 数据通信 (read()/write()) 关闭连接 (close()) 客户端流程&#xff1a; 创建Socket (socket()) 连接…

Redis-x64-3.2.100.msi : Windows 安装包(MSI 格式)安装步骤

Redis-x64-3.2.100.msi 是 Redis 的 Windows 安装包&#xff08;MSI 格式&#xff09;&#xff0c;适用于 64 位系统。 在由于一些环境需要低版本的Redis的安装包。 Redis-x64-3.2.100.msi 安装包下载&#xff1a;https://pan.quark.cn/s/cc4d38262a15 Redis 是一个开源的 内…

4.7正则表达式

1.字符匹配 一般字符匹配自身. 匹配任意字符(换行符\n除外),一个点占一位\转义字符&#xff0c;使其后一个字符改变原来的意思(\.就是.)[......]字符集,对应的位置可以是字符集中的任意字符.字符集中的字符可以逐个列出,也可以给出范围如[abc]或[a-c] [^abc] 表示取反&#xf…

Fortran 中读取 MATLAB 生成的数据文件

在 Fortran 中读取 MATLAB 生成的数据文件&#xff0c;可以通过以下几种方法实现&#xff0c;包括使用开源工具和手动解析&#xff1a; 1. 使用开源工具&#xff1a;MATFOR MATFOR 是一个商业/开源混合工具&#xff08;部分功能免费&#xff09;&#xff0c;提供 Fortran 与 M…

压测工具开发实战篇(四)——client子窗口功能

你好&#xff0c;我是安然无虞。 文章目录 树控件添加文件补充学习: 函数定义中循环体里的局部变量补充学习: 动态添加对象属性 刷新文件上下文菜单 (右键菜单)实现右键菜单功能 编辑节点文本 在学习本篇文章之前, 建议先看一下上篇介绍MDI子窗口的文章: 压测工具开发实战篇(三…

PyTorch使用(4)-张量拼接操作

文章目录 张量拼接操作1. torch.cat 函数的使用1.1. torch.cat 定义1.2. 语法1.3. 关键规则 1.4. 示例代码1.4.1. 沿行拼接&#xff08;dim0&#xff09;1.4.2. 沿列拼接&#xff08;dim1&#xff09;1.4.3. 高维拼接&#xff08;dim2&#xff09; 1.5. 错误场景分析1.5.1. 维度…

linux命令之yes(Linux Command Yes)

linux命令之yes 简介与功能 yes 命令在 Linux 系统中用于重复输出一行字符串&#xff0c;直到被杀死&#xff08;kill&#xff09;。该命令最常见的用途是自动化控制脚本中的交互式命令&#xff0c;以便无需用户介入即可进行连续的确认操作。 用法示例 基本用法非常简单&am…

《算法笔记》10.3小节——图算法专题->图的遍历 问题 B: 连通图

题目描述 给定一个无向图和其中的所有边&#xff0c;判断这个图是否所有顶点都是连通的。 输入 每组数据的第一行是两个整数 n 和 m&#xff08;0<n<1000&#xff09;。n 表示图的顶点数目&#xff0c;m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据…