文件上传下载系列——如何实现文件秒传

news/2025/1/22 8:30:29/

文章目录

🎃简介:

👻核心思想:

MD5是什么?

实现步骤:

🎄实操:

1、java生成文件MD5码

2、javascript生成文件MD5码

⛳️基于秒传的分片上传下载

上传:

下载:

🍢MD5存储位置

1、持久化到数据库中

2、存储到redis中

🎋总结


🎃简介:

        文件秒传是指在文件上传过程中,如果上传的文件已经在服务器中存在,那么服务器会直接将已经存在的文件的信息返回给客户端,而不需要客户端再次上传文件,从而实现文件的秒传。所以,无论任何大小、格式的文件都可以实现秒传。

        文件秒传通常在云存储和文件共享服务中应用广泛。这种技术能够节省用户上传大文件的时间和带宽,提高文件传输的效率和速度。

        例如,百度云盘、阿里云OSS、腾讯云COS等云存储服务都支持文件秒传技术。

👻核心思想:

        将文件压缩成128位的MD5哈希值,只要修改文件内容,MD5码就会改变,用MD5码来判断是否是同一文件。

        将MD5码存到数据库中,当有文件上传,首先查询MD5码是否重复,如果重复则不需要上传,通过这种形式实现文件的秒传。

MD5是什么?

 

        MD5是一种信息摘要算法,原理是通过将输入数据分块,并对每个数据块进行填充、迭代压缩和更新哈希值的方式,最终得到一个128位的哈希值。

  • 不可逆性:信息摘要算法对原数据进行了压缩,无法逆向推导出原始数据
  • 唯一性:由于MD5哈希函数的输出长度为128位,因此总共可以生成2^128个不同的哈希值。(但也是有可能存在哈希碰撞的风险,在一些对安全性要求较高的应用场景下,建议使用更加安全的哈希算法,如SHA-2、SHA-3等)
  • 高效性:MD5算法的设计相对简单,它主要由四个轮函数和一个级联结构组成,这些运算和函数能够快速地对输入数据进行处理,从而提高了算法的执行效率;将输入数据分块,消息块之间的处理是相互独立的,因此可以并行处理,从而提高了处理的效率。

实现步骤:

        文件秒传的实现可以分为以下几个步骤:

  1. 客户端向服务器发送一个上传请求,包含要上传的文件的信息(例如文件名、大小、MD5值等)。
  2. 服务器根据客户端提供的文件信息,查询服务器上是否已经存在相同的文件,如果存在则返回文件已经存在的标识。
  3. 前端接到消息,显示已上传成功。

🎄实操:

1、java生成文件MD5码

        引入的文件

  • java.security.MessageDigest类中有MD5、SHA等加密算法的实现,这里使用其中的MD5算法实现。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*** 生成文件的MD5值* @param filePath 文件路径* @return 文件的MD5值*/
public static String getFileMD5(String filePath) {FileInputStream fis = null;try {MessageDigest md = MessageDigest.getInstance("MD5");fis = new FileInputStream(new File(filePath));byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) != -1) {md.update(buffer, 0, length);}byte[] digest = md.digest();StringBuilder sb = new StringBuilder();for (byte b : digest) {sb.append(String.format("%02x", b & 0xff));}return sb.toString();} catch (NoSuchAlgorithmException | IOException e) {e.printStackTrace();return null;} finally {if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}
}

        调用的示例代码:

/*** 秒传*/
public void quickLoad() {String filePath = "E:\\DRP.avi"; // 文件路径String md5 = getFileMD5(filePath);System.out.println(md5); // 输出文件的MD5值
}

        生成的MD5码:

2、javascript生成文件MD5码

function generateFileMD5(file, callback) {const reader = new FileReader();reader.readAsArrayBuffer(file);reader.onload = () => {const buffer = reader.result;const crypto = window.crypto || window.msCrypto;const digestAlgorithm = "MD5";const cryptoSubtle = crypto.subtle || crypto.webkitSubtle;cryptoSubtle.digest(digestAlgorithm, buffer).then((digest) => {const hashArray = Array.from(new Uint8Array(digest));const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');callback(hashHex);}).catch((error) => {console.error(error);});};
}

        调用此函数时,需要传入文件对象和回调函数。回调函数将在计算MD5值完成后被调用,并且它将接收计算出的MD5值作为参数。以下是调用该函数的示例代码:

const file = document.getElementById("file-input").files[0]; // 获取文件对象
generateFileMD5(file, (hash) => {console.log(hash); // 输出文件的MD5值
});


⛳️基于秒传的分片上传下载

        分片上传是指将一个大文件拆分成多个小块进行上传,上传完成后再将小块合并。

 

上传:

        基于秒传实现分片上传,可以先将文件进行分片并计算出每个分片的MD5值,然后将这些分片和MD5值上传到服务器中存储起来。

        服务器在接收到分片和MD5值后,可以根据MD5值查找Redis中是否已经存在相同的文件。

  • 如果存在,则返回该文件的唯一标识符。对于已上传的分片,服务器将其保存到临时文件夹中,同时记录下该分片的位置信息,这就实现了文件片秒传
  • 如果不存在,则根据分片的MD5值判断哪些分片已经上传,哪些分片还需要继续上传。对于未上传的分片,服务器返回需要继续上传的分片索引,客户端根据索引上传相应的分片数据。

        当所有分片都上传完成后,服务器将所有分片进行合并,并生成一个唯一的文件标识符,将该标识符和文件信息存储到Redis中。

下载:

        客户端通过文件标识符下载文件时,服务器根据标识符从Redis中获取文件信息,再根据分片位置信息将文件分片进行合并,并返回给客户端。


🍢MD5存储位置

1、持久化到数据库中

  • 优点:方便查找和比较,数据库中的数据不会丢失。
  • 缺点:需要在数据库中创建表以存储MD5值,并确保所有相关文件都已添加到数据库中。

2、存储到redis中

  • 优点:查找速度快,减少网络时延。
  • 缺点:redis的数据存在内存中,数据有丢失的风险,可以设置在开启服务器时自动去数据库取出数据存到redis中。redis存储有限,过多的数据会无法存储,需要综合考量。

 

🎋总结

        文件秒传的优点在于,对于同一份文件,无论是上传者还是下载者,都可以利用已有的文件块或者整个文件的信息进行操作,不需要重复传输数据,节省了时间和网络资源。这种技术不仅提高了文件上传的效率,也为用户节省了成本,减少了网络带宽的消耗。

        文件秒传也同样存在缺点,首先是安全性问题,如果黑客可以伪造MD5值,则可能存在安全性问题。另外,如果服务器已经存在相同的文件,但是该文件已经损坏或者不完整,秒传可能会导致上传的文件也是不完整的。如果我们选择依赖redis,当Redis出现问题,可能导致秒传失败或者数据丢失。

        总的来说,文件秒传可以带来很多好处,但也存在一些安全性和数据完整性方面的问题需要注意。需要在实现时进行充分的测试和验证,并采取适当的措施保障数据安全和完整性。

        关于文件上传下载设计到的知识点,打算做一个系列进行分享,大家多多评论,感谢阅读!

 


http://www.ppmy.cn/news/56946.html

相关文章

交叉熵损失函数原理详解

交叉熵损失函数原理详解 在学习pytorch的神经网络模型里,经常用到交叉熵损失函数(CrossEntropy Loss),只知道它是分类问题中经常使用的一种损失函数,对于其内部的原理总是模模糊糊,而且一般使用交叉熵作为损失函数时,…

【Python】操作MySQL

一、Python 操作 Mysql的方式 Python 操作 Mysql 主要包含下面 3 种方式: Python-MySql Python-MySql 由 C 语法打造,接口精炼,性能最棒;但是由于环境依赖多,安装复杂,已停止更新,仅支持 Python…

密码学【java语言】初探究

文章目录 前言一 密码学1.1 古典密码学1.1.1 替换法1.1.2 移位法1.1.3 古典密码破解方式 二 近代密码学2.1 现代密码学2.1.1 散列函数2.1.2 对称密码2.1.3 非对称密码 二 凯撒加密的实践2.1 基础知识:ASCII编码2.2 ascii编码演示2.3 凯撒加密和解密实践2.4 频率分析…

多项式加法(用 C 语言实现)

目录 一、多项式的初始化 二、多项式的创建 三、多项式的加法 四、多项式的输出 五、清除链表 六、主函数 用链表实现多项式时,每个链表节点存储多项式中的一个非零项,包括系数(coef)和指数(exp)两个…

权限提升:漏洞探针.(Linux系统)

权限提升:漏洞探针. 权限提升简称提权,由于操作系统都是多用户操作系统,用户之间都有权限控制,比如通过 Web 漏洞拿到的是 Web 进程的权限,往往 Web 服务都是以一个权限很低的账号启动的,因此通过 Webshel…

python-使用Qchart总结3-绘制曲线图

1.将画好的图表关联 解释说明图 2.新建一个文件画曲线图,并关联到UI的py文件上,上代码 import sys from PyQt5.Qt import * from PyQt5.QtChart import QChartView, QChart, QValueAxis, QSplineSeries from PyQt5.QtGui import QPainter, QColor, QFon…

5月2日第壹简报,星期二,农历三月十三

5月2日第壹简报,星期二,农历三月十三坚持阅读,静待花开1. “港车北上”政策公布:6月1日起接受申请,7月1日起可驶入广东,将惠及45万香港车主。2. 全球女性第一人!董红娟登顶全部14座8000米级高峰…

【代码随想录】刷题Day14

递归实现的一些理解 1.如果是链表的遍历其实不需要怎么思考;无非就是先定参数然后考虑是先操作后遍历还是先走到底再操作。 包括我之前在写链表的节点删除其实核心思路就是由于链表前面删除后面找不到的原理,以至于我们需要走到链表的底部再进行操作。 2…