文件上传之秒传功能

        秒传是一种文件的传输机制,用于在文件已经存在于目标服务器上时,通过校验文件的唯一标识,实现快速而无需从新上传整个文件,它解决了重复上传相同文件的问题,提高了文件传输的效率和节省了带宽资源。

技术阐述: 

那么,我们需要对文件上传的需求原理实现方式以及优势与不足进行对应的理解。

        需求:避免重复上传操作是一个非常重要的问题,当用户需要上传一个以及存在于服务器上的文件时,需要去避免重复上传,因为可以节省时间和资源带宽。这样的目的是可以进行更高效率的提升,减少用户的等待时间。并且秒传功能减少了不必要的网络传输操作,节省了带宽的资源,提升了整体的网络性能。

        实现原理:秒传的实现原理是基于文件的唯一标识进行校验,文件的唯一标识通常使用文件的哈希值,例如MD5或SHA来进行展示。在文件上传之前,客户端先进行文件的哈希值计算,然后将其发送到服务器端。而服务器端接收到哈希值以后,检查是否以及存在该哈希值对应的文件内容,如果已经存在,则不需要进行文件的上传操作,可以直接中断上传,实现秒传的功能。如果不存在,我们则需要进行文件的上传处理。

如何去实现秒传操作,首先需要去注意几个核心的关键技术点:

        (1)哈希值的计算:客户端需要先计算出文件的哈希值,那么我们需要去思考,是对什么内容进行哈希值的计算。是对文件名还是文件后缀。如果说文件名修改以后,这个文件是否还是我们同一个需要上传的文件。所有,哈希值的计算是根据文件的内容进行计算处理,因为即便对文件名进行了修改,但是文件内容本质没有发生任何的改变,所以文件还应该是相同的文件。所以哈希值的计算是秒传实现原理的根本。

那么我们通常使用的是MD5或SHA等算法来进行哈希值的计算,这是因为它会产生一个唯一标识。那么客户端将这个哈希值发送到服务器端以后,服务器端则进行存储与检测操作。

事实上,实现秒传功能是为了避免上传相同的文件节省传输的时间和资源。不光是客户端的时间资源进行了节省,更重要的是服务器端的时间和资源也得到了最大的利用。其实是可以给服务器进行了费用的节省。

那么用户的友好性,体验也会得以更好的提升。

当然,在秒传的过程当中,还会存在一些不足点,因为唯一标识可能会产生冲突的问题。不同的文件得到的哈希值是相同的,可能会导致唯一标识产生冲突。需要额外的校验机制来去解决这个问题。当然,这种情况应该是发生几率是非常少的,但是不能够进行排除。

而且服务器端也必须要支持秒传的功能,因为,服务器端和客户端的哈希值进行校验的话,是对应的一个关系。

总而言之,秒传是一种通过校验文件唯一标识实现快速传输已经存在文件而无需重新上传的机制。它提高了文件的传输效率,节省了时间和带宽,提供了更好的用户体验,所以,我们需要去尝试进行文件秒传的功能实现。

如何实现:

文件上传之大文件分块上传-CSDN博客

大文件分块上传进度控制处理-CSDN博客

大文件分块上传之断点续传-CSDN博客

在以上三个博客的基础上进行实现的

第一步:定义一个计算哈希值函数

需要引入第三方库

<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/spark-md5/3.0.2/spark-md5.min.js"></script>
const computeFileHash = (file) => { //传入文件内容  对文件内容进行哈希值的计算return new Promise((resolve, reject) => {const chunkSize = 1 * 1024 * 1024; // 1MBconst fileReader = new FileReader() // 创建一个FileReader对象,用于读取文件内容const spark = new SparkMD5.ArrayBuffer(); // 创建一个SparkMD5对象,用于计算文件哈希值let currentChunk = 0; // 当前处理的分片索引// 文件读取成功时的回调函数fileReader.onload = function(e) {spark.append(e.target.result); //将文件块的数据添加到哈希计算中currentChunk++;if(currentChunk < totalChunks){loadNextChunk(); //继续加载下一个文件块}else{const hash = spark.end(); //完成哈希值计算resolve(hash); //返回计算得到的哈希值}};// 文件读取失败时的回调函数fileReader.onerror = function (e) {reject(e.target.error); // 返回读取错误};// 加载下一个文件块function loadNextChunk() {const start = currentChunk * chunkSize; //当前文件块的起始位置const end = Math.min(start + chunkSize, file.size); //当前文件块的结束位置const chunk = file.slice(start, end); // 提取当前文件块的数据fileReader.readAsArrayBuffer(chunk); // 以ArrayBuffer形式读取文件块的数据}const totalChunks = Math.ceil(file.size / chunkSize); // 总的文件块数量loadNextChunk(); // 开始加载第一个块})
}

第二步:如何使用这个方法

在while循环前调用这个方法,将文件的哈希值传递到服务器

// 计算文件哈希值
const fileHash = await computeFileHash(file);// 检查服务器是否已存在相同的文件
try{const response = await axios.head('http://localhost:3000/check-file?filehash=' + fileHash);if(response.status === 200){// 文件已存在,直接完成上传console.log('文件已存在,秒传成功');return;}
}catch(error){console.log('检查文件失败',error)
}

第三步:在文件合并的时候去确认这个文件信息是否应该包含fileHash值。

这样可以确认文件是否已经在服务器中存在

try{const postData = { filename:file.name,totalChunks:totalChunks,fileHash:fileHash }; //构造合并请求的数据await http.post('http://localhost:3000/merge', postData,{headers: {'Content-Type': 'application/json'}}); //发送合并请求
}catch(error){console.error(error);
}

以上则是客户端的代码。

第四步:在服务器端定义一个存放哈希值的对象

// 存储文件哈希值的对象
const fileHashes = {};

第五步:在merge接口中进行一些修改  用来存储哈希值

第六步:检查文件是否已存在

前端check-file接口

// 检查文件是否已存在
app.head('/check-file',(req,res) => {const fileHash = req.query.filehash;console.log(fileHash,fileHashes);if(fileHashes[fileHash]){res.sendStatus(200); //文件已存在}else{res.sendStatus(404); //文件不存在}
})

 执行代码:

秒传功能就已经实现了,无论是我们修改文件名称,也会进行一个秒传的效果,因为我们是对块进行哈希值的一个计算。

那么以上就是秒传内容,希望对您有所帮助。

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

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

相关文章

免 费 小程序商城搭建之鸿鹄云商 SAAS云产品概述

【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营…

软件测试面试八股文(2024新版)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发…

【unity实战】实现蓄力丢手榴弹、烟雾弹、燃烧弹的效果

文章目录 爆炸燃烧烟雾效果资产手榴弹丢手雷烟雾弹、燃烧弹实现手雷每次撞墙弹发出音效&#xff08;补充&#xff09;完结 爆炸燃烧烟雾效果资产 https://assetstore.unity.com/packages/vfx/particles/war-fx-5669 手榴弹 手榴弹配置好刚体&#xff0c;碰撞体 新增脚本Th…

IO流-处理流之——对象流(序列化)

IO流-处理流之——对象流&#xff08;序列化&#xff09; 1.数据流及其作用&#xff08;了解&#xff09;2.对象流及其作用3.对象的序列化机制是什么4.如下两个过程使用的流&#xff1a;5.自定义类要想实现序列化机制&#xff0c;需满足&#xff1a;6.注意点&#xff1a; 1.数据…

Qlik Sense : Store With Retry (保存重试机制)

Background sometime you cannot store the file directly ,maybe there are another process are reading/storeing the file , so you would need to wait another proecess done and retry . then we come up this solution . 有时您不能直接存储文件&#xff0c;可能还有…

Jenkins CLI 任意文件读取漏洞复现(CVE-2024-23897)

0x01 产品简介 Jenkins 是一个开源的自动化服务器软件,用于构建、测试和部署软件项目。它提供了一种强大的方式来自动化软件开发和交付流程,以提高开发团队的效率和生产力。 0x02 漏洞概述 漏洞成因 命令行接口文件读取: Jenkins内置的命令行接口(CLI)存在一个特性,允…

实验:eNSP AR通过telnet远程登录另外一台AR

实验2&#xff1a;eNSP AR通过telnet远程登录另外一台AR 基于实验1的基础上来进行&#xff0c;我们通过AR2220登录AR3260 首先设置远程登录密码 1、user-interface vty 0 4 进入用户的虚拟终端 2、设置密码 set authentication password cipher Huawei 这里的意思就是设置密…

org.springframework.util.StringUtils 下StringUtils工具类

目录 1.isEmpty 1.1.可以判断字符串是否为空或 null 1.2.可以判断Integer类型的数据是否为空 1.isEmpty 1.1.可以判断字符串是否为空或 null Testpublic void test() {/*** StringUtils.isEmpty 判断是空*/String username "123456";System.out.println(Strin…

数据结构(C语言版)代码实现(四)——静态单链表的部分代码实现

目录 参考材料、格式 头文件SLinkList.h 库、宏定义、函数类型声明 线性表的静态单链表存储结构 按值查找 初始化静态链表 分配空间 回收空间 打印已用链表中的元素 求集合(A-B)U(B-A)中的元素&#xff08;重点介绍&#xff09; 调试过程 修改报错与警告 调试 完整…

找不到msvcp110.dll怎么办,msvcp110.dll丢失修复方法分享

当计算机系统中无法找到msvcp110.dll这个特定的动态链接库文件时&#xff0c;可能会引发一系列运行问题和功能受限的情况。msvcp110.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序来说&#xff0c;它是至关重要的运行组件…

vue模拟聊天页面列表:滚动到底部,滚动到顶部触发加载更多

先看下效果&#xff1a; 代码&#xff1a; <template><div><div style"text-align: center"><button click"scrollTop">滚动到顶部</button><button click"scrollBottom">滚动到底部</button></d…

Vue深入学习2—虚拟DOM和Diff算法

1、snabbdom 是什么&#xff1f; snabbdom是“速度"的意思&#xff0c;源码只有200行&#xff0c;使用TS写的&#xff0c;让东西变得模块化 2、snabbdom 的 h 函数如何工作&#xff1f; h函数用于产生虚拟节点&#xff0c;同时也可以嵌套使用&#xff0c;得到虚拟DOM树&am…

kuberneters可视化界面-kuboard

一、kuboard安装 可以选用&#xff0c;docker和docker-commpose kuberneters 安装 kuboard官网 1、 docker安装 sudo docker run -d \--restartunless-stopped \--namekuboard \-p 80:80/tcp \-p 10081:10081/tcp \-e KUBOARD_ENDPOINT"http://192.168.1.10:80" …

linux的kali安装,换源,更新包

下载kali kali.org进入官网后点第二个 然后点第一个 解压kali 下载后获得.7z压缩包&#xff0c;建议移动到合适自己电脑的位置进行解压&#xff0c;我喜欢放在D盘 启动kali 双击进入解压出的文件夹&#xff0c;将唯一一个.vmx文件用vmware打开&#xff08;没装的自行提前装…

数据结构奇妙旅程之二叉树题型解法总结

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

【数据库】oracle常见语句

一、查询 查询员工表所有数据 select * from emp查询职位(JOB)为’PRESIDENT’的员工的工资 select sal from emp where jobPRESIDENT查询佣金(COMM)为0或为NULL的员工信息 select * from emp where comm0 or comm is null查询入职日期在 1981-5-1到1981-12-31之间的所有员…

滑动窗口(算法)

一、算法分享&#xff1a;滑动窗口 原题描述&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 思路 定义一个 map 数据结构存储 (k, v)&#xff0c;其中 key 值为字符&#xff0c;value 值为字符位置 1&#xff0c;加 1 …

【深度学习】CodeFormer训练过程,如何训练人脸修复模型CodeFormer

文章目录 BasicSR介绍环境数据阶段 I - VQGAN阶段 II - CodeFormer (w0)阶段 III - CodeFormer (w1) 代码地址&#xff1a;https://github.com/sczhou/CodeFormer/releases/tag/v0.1.0 论文的一些简略介绍&#xff1a; https://qq742971636.blog.csdn.net/article/details/134…

链路追踪-调用链跟踪-Jaeger

文章目录 一、什么是链路跟踪二、OpenCensusOpenCensus 主要特点OpenTracing标准基本概念Span 三、典型服务端产品什么是OpenTracing?opentracing 使用介绍 四、JaegerJaeger 包含的模块Jaeger-client&#xff08;客户端库&#xff09; 五、Jaeger服务容器化部署过程问题整理 …

csdn黑色背景用法

在edge浏览器下&#xff0c;下载油猴脚本管理器 脚本下载 edge扩展 效果图如下&#xff1a;&#xff1a;&#xff1a;