切片上传记录

核心就是

1 前端分片

2 后端组装

3 md5校验

Spark-md5介绍

用md5就是为了防止文件被篡改,小的文件直接可以用整个文件传入,返回文件md5,但是越大的文件(超过2G),如果用整文件的方式,时间会很久,分片计算md5会节约时间;另外MD5算法是一个单向哈希函数,不可逆的。

官网介绍:spark-md5

官网demo

来分析下官网的例子


<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>incremental md5</title><style>body{text-align:center;font:13px Tahoma}form{margin:9vh auto}pre{background:#ffd;border:1px solid orange;padding:1em;margin:0 auto;display:none;text-align:left;line-height:1.25}</style></head><body><h1>incremental md5 demo</h1><h3>with <a target="_blank" href="//github.com/satazor/SparkMD5">SparkMD5</a></h3><form method="POST" enctype="multipart/form-data" onsubmit="return false;" ><input id=file type=file placeholder="select a file" /></form><pre id=log></pre><script src="//cdn.rawgit.com/satazor/SparkMD5/master/spark-md5.min.js"></script><script>var log=document.getElementById("log");document.getElementById("file").addEventListener("change", function() {var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,file = this.files[0],chunkSize = 2097152, // read in chunks of 2MBchunks = Math.ceil(file.size / chunkSize), // 要分成几片currentChunk = 0,spark = new SparkMD5.ArrayBuffer(), // 初始化MD5实例frOnload = function(e){log.innerHTML+="\nread chunk number "+parseInt(currentChunk+1)+" of "+chunks;spark.append(e.target.result); // append array buffer 追加缓冲currentChunk++;if (currentChunk < chunks)loadNext();elselog.innerHTML+="\nfinished loading :)\n\ncomputed hash:\n"+spark.end()+"\n\nyou can select another file now!\n"; // 结束},frOnerror = function () {log.innerHTML+="\noops, something went wrong.";};function loadNext() {var fileReader = new FileReader();fileReader.onload = frOnload;fileReader.onerror = frOnerror;var start = currentChunk * chunkSize,end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));};log.style.display="inline-block";log.innerHTML="file name: "+file.name+" ("+file.size.toString().replace(/\B(?=(?:\d{3})+(?!\d))/g, ',')+" bytes)\n";loadNext();});</script></body>
</html>

核心的就是这三个:

spark = new SparkMD5.ArrayBuffer(),

spark.append()

spark.end()

前端实现

前端要怎么分块,核心代码,chunkSize有高手建议不要超过5M,计算出起始和结束的字节数,用

File.prototype.slice来截取

 const start = currentChunk * chunkSize;const end = start + chunkSize >= file.size ? file.size : start + chunkSize;const blobSlice = File.prototype.slice;const blob = blobSlice.call(file, start, end);

然后把这一部分的blob算出切片的md5,一并发给后端后发送merge请求

后端实现

上传接口

包括切片的index,切片的md5,文件名称

如果当前分片文件不存在,则存储

import * as fse from "fs-extra";
const outStream = fse.createWriteStream(chunkPath);
const inStream = Readable.from(file.stream ?? file.buffer); //blob
inStream.pipe(outStream);

merge

合并文件

// 分片循环
const buffer = await fse.readFile(chunkPath);
await fse.appendFile(finalPath, buffer);

剩余的一些问题

1 上传过程中,如果刷新页面,或者网络问题,断点续传的考虑, 需要后端存储切片信息,发给前端已有切片index,前端再重新继续切片请求

2 校验已有文件,无需重传

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

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

相关文章

bladeX默认审批流flowable如何设置

下面就是流程图必须得写 ${taskUser} 你要配什么 就给审批流的service传什么

VSCode必备插件!快看过来!

同学同学&#xff0c;你是不是也很头疼VSCode不知道安装什么插件啊&#xff1f;尤其是萌新小白&#xff0c;更是一头雾水&#xff0c;那就快来一起看看吧~我帮你整理了一些非常实用的插件&#xff0c;安装上它们&#xff0c;你的开发体验会大大提升&#xff01; 1. Chinese (S…

Python变量未赋值错误之程序优化示例

UnboundLocalError: local variable ‘respon1’ referenced before assignment V1: def main(): time1=2024-08-01 08:00:00 # 开始 08:00:00time2=2024-09-01 07:59:59 # 结束 07:59:00begintime=str_data_to_num(time1)endtime=str_data_to_num(time2)ss=get_grafana_l…

Call openai-node in the backend or call https in the frontend?

题意&#xff1a;在后端调用 openai-node 还是在前端调用 https&#xff1f; 问题背景&#xff1a; I have a web application by ReactJS and Nodejs. This application calls OpenAI APIs. 我有一个使用 ReactJS 和 Node.js 开发的 Web 应用程序。这个应用程序调用 OpenAI …

零基础入门转录组数据分析——预后模型之lasso模型

零基础入门转录组数据分析——预后模型之lasso模型 目录 零基础入门转录组数据分析——预后模型之lasso模型1. 预后模型和lasso模型基础知识2. lasso预后模型&#xff08;Rstudio&#xff09;——代码实操2. 1 数据处理2. 2 构建lasso预后模型2. 3 提取Lasso预后基因2. 4 计算风…

数据库性能测试2:内存数据库

继上一篇 数据库性能测试&#xff1a;Mysql、Sqlite、Duckdb 之后&#xff0c;做了一下内存数据库的性能测试&#xff0c;这里主要比较的是 Sqlite、Duckdb以及我这边使用容器实现的一个简单内存数据库&#xff0c;因为Sqlite和Duckdb都支持内存数据库模式&#xff0c;于是打算…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

目录 一、多线程任务和多窗体交互 二、增删改查Demo 三、UI设计 【css效果代码对照表】 【实现效果】 【实现代码】 【常见问题】 Q1&#xff1a;工具栏怎么加&#xff0c;资源图片怎么加 Q2&#xff1a;控件被背景染色怎么办&#xff1f; Q3&#xff1a;QTdesigner有…

LVS的加权轮询算法

http://kb.linuxvirtualserver.org/wiki/Weighted_Round-Robin_Scheduling 加权轮循调度是为了更好地处理不同处理能力的服务器。每个服务器都可以被分配一个权重&#xff0c;一个表示处理能力的整数值。权值较高的服务器比权值较低的服务器首先接收到新连接&#xff0c;权值较…

<Rust>egui学习之小部件(七):如何在窗口中添加颜色选择器colorpicker部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第七篇博…

c#中Task.Run 和使用 Task 构造函数创建任务的区别

Task.Run 和使用 Task 构造函数创建任务是两种不同的方法&#xff0c;它们在某些方面有显著的区别&#xff1a; 启动方式: Task.Run 是一个静态方法&#xff0c;它立即启动一个任务并在后台执行指定的工作。它通常用于快速启动一个简单的后台任务。使用 Task 构造函数创建任务&…

记一次学习--webshell绕过(利用清洗函数)

目录 样本 样本修改 样本 <?php $a array("t", "system"); shuffle($a); $a[0]($_POST[1]); 通过 shuffle 函数打乱数组,然后通过$a[0]取出第一个元素&#xff0c;打乱后第一个元素可能是t也可能是system。然后再进行POST传参进行命令执行。 这里抓…

Android14(U)文件扫描源码探究

1.MediaReceiver 扫描的功能集中在MediaProvider中&#xff0c;源码位置&#xff1a;packages/providers/MediaProvider 其中的packages/providers/MediaProvider/AndroidManifest.xml&#xff1a; <receiver android:name"com.android.providers.media.MediaReceive…

部署Rancher2.9管理K8S1.26集群

文章目录 一、实验须知1、Rancher简介2、当前实验环境 二、部署Rancher1、服务器初始化操作2、部署Rancher3、登入Rancher平台 三、Rancher对接K8S集群四、通过Rancher仪表盘部署Nginx服务1、创建命名空间2、创建Deployment3、创建Service 一、实验须知 1、Rancher简介 中文官…

【自由能系列(中级),代码模拟】预测编码的核心:三个关键方程式的详解

预测编码的核心&#xff1a;三个关键方程式的详解 ——探索预测编码背后的数学原理与应用 核心结论&#xff1a;预测编码是一种基于贝叶斯定理的理论框架&#xff0c;它通过三个关键方程式描述了大脑如何处理和解释来自环境的信号。这些方程式分别建立了贝叶斯定理的简化形式、…

JL-02 投入式水位记录仪 采集记录一体 安装便捷

产品概述 水位记录仪是针对市场需求而研发的集成了信号采集、过程IO控制和无线数据通信于一体的高性能测控装置&#xff1b;采用低功耗技术&#xff0c;可使用太阳能、蓄电池供电&#xff0c;非常适合在野外供电条件困难的恶劣环境使用&#xff1b;安装使用方便&#xff0c;不…

9月新机首发:骁龙芯片+超大电池,游戏玩家的终极选择

随着秋风送爽的9月到来&#xff0c;智能手机和电子设备市场也迎来了新一轮的热潮。8月份的新机发布热潮刚刚退去&#xff0c;9月份的新机已经迫不及待地揭开了神秘的面纱。在众多备受期待的产品中&#xff0c;红魔品牌抢先官宣&#xff0c;两款全新的游戏平板将在9月5日正式亮相…

论文速读|通过人类远程操作的深度模仿学习框架:人型机器人的行走操纵技能

项目地址&#xff1a;Deep Imitation Learning for Humanoid Loco-manipulation through Human Teleoperation 本文详细介绍了 TRILL&#xff08;Teleoperation and Imitation Learning for Loco-manipulation&#xff09;框架&#xff0c;它是一个用于人型机器人行走操纵技能训…

LeetCode - 12 整数转罗马数字

题目来源 12. 整数转罗马数字 - 力扣&#xff08;LeetCode&#xff09; 题目描述 七个不同的符号代表罗马数字&#xff0c;其值如下&#xff1a; 符号值I1V5X10L50C100D500M1000 罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规…

OpenCV绘图函数(14)图像上绘制文字的函数putText()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在图像上绘制指定的文本字符串。 cv::putText 函数在图像上绘制指定的文本字符串。无法使用指定字体渲染的符号会被问号&#xff08;?&#xff…

git把远程仓库的master分支合并到本地分支

假如现在我们要将远程 origin 的 master 分支合并到本地的 dev 分支&#xff0c;可以按照以下步骤进行操作&#xff1a; 切换到本地的 dev 分支&#xff1a; git checkout dev拉取远程 origin 的最新 master 分支&#xff1a; git fetch origin master将远程 origin 的 master …