minio spring boot 秒传、分片上传、断点续传文件实现
此处后端使用的是前期封装的自定义starter,具体链接可参考:minio对象存储spring boot starter封装组件
这里主要针对前期封装的组件,做一个简单的应用,前端直传可查看之前的文章
秒传
秒传的逻辑比较简单,在前传上传之前,先获取到对应文件的md5,传给后端,后端校验md5是否已经存在,存在则直接提示上传成功,否则,发起文件上传请求
获取文件MD5,前端可以使用spark-md5
或者crypto-js
<el-upload class="upload-demo" drag action="#" :http-request="sparkUploadHandle" :show-file-list="false"><el-icon class="el-icon--upload"><UploadFilled /></el-icon><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
对应的处理逻辑
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import SparkMD5 from 'spark-md5'
import { checkMd5 } from '@/api/file'
import { UploadFilled } from '@element-plus/icons-vue'const sparkUploadHandle = (param: any) => {const file = param.fileconst fileReader = new FileReader()const Spark = new SparkMD5.ArrayBuffer()fileReader.readAsArrayBuffer(file)fileReader.onload = function (e) {Spark.append(e.target.result)const md5 = Spark.end()ElMessage.success('文件MD5:' + md5)//上传逻辑处理const data = {md5: md5,fileName: file.name}checkMd5(data).then(resp => {if (resp.code == 201) {ElMessage.success('秒传成功')} else {ElMessage.info('后台无数据,正在上传中....')//请求上传接口}})}
}
</script>
checkMd5
就是请求后端接口,查看是否存在
分片上传
这里使用的是前端直传方式的分片上传,处理逻辑:前端根据指定的大小对文件进行分片,分片完成后,根据文件名和分片数量去请求后端,获得对应的分片上传地址集合,再根据返回的地址集合,进行前端直传,传完后,调用后端接口,合并分片
后端接口
后端拿到对应的文件名称,分片大小和文件类型,然后返回给前端对应的put直传地址集合,每个直传地址默认10分钟的有效期
@Autowiredprivate MinioService minioService;@GetMapping("/part-url")public RestResult<MultiPartUploadInfo> partUrl(@RequestParam String fileName,@RequestParam int partSize, @RequestParam String contentType) throws MinioException {MultiPartUploadInfo uploadInfo = minioService.initMultiPartUploadId("bucketName", fileName, partSize, contentType);return RestResult.ok(uploadInfo);}@GetMapping("/merge-part")public RestResult<String> mergePart(@RequestParam String fileName, @RequestParam String uploadId) throws MinioException {String merge = minioService.mergeMultiPartUpload("bucketName", fileName, uploadId);return RestResult.ok(merge);}
前端
<el-upload class="upload-demo" drag action="#" :http-request="partUploadHandle" :show-file-list="false"><el-icon class="el-icon--upload"><UploadFilled /></el-icon><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
import { reactive } from 'vue'
import service from '@/utils/request'
import { getPartUrl, mergePart } from '@/api/file'
import { UploadFilled } from '@element-plus/icons-vue'const state = reactive({uploadId: ''
})
//分片大小
const chunkSize = 50 * 1024 * 1024const partUploadHandle = (param: any) => {let file = param.file// 正在创建分片let fileChunks = createFileChunk(file)let data = {fileName: file.name,partSize: fileChunks.length,contentType: file.type}//获得上传的urlgetPartUrl(data).then(resp => {state.uploadId = resp.data.uploadIdlet uploadUrls = resp.data.uploadUrlsif (fileChunks.length !== uploadUrls.length) {ElMessage.error('文件分片上传地址获取错误')return}let chunkList = []fileChunks.map((chunkItem, index) => {chunkList.push({chunkNumber: index + 1,chunk: chunkItem,uploadUrl: uploadUrls[index],progress: 0,status: '—'})})//上传分片uploadChunkBase(chunkList, file.type).then(resp => {console.log('分片上传完成')let par = {fileName: file.name,uploadId: state.uploadId}//请求后端合并分片mergePart(par).then(resp => {ElMessage.info('上传成功,访问地址:' + resp.data)})})})
}/*** 文件分片*/
const createFileChunk = (file, size = chunkSize) => {const fileChunkList = []let count = 0while (count < file.size) {fileChunkList.push({file: file.slice(count, count + size)})count += size}return fileChunkList
}
//分片上传
const uploadChunkBase = (chunkList, contentType = 'application/octet-stream') => {let successCount = 0let totalChunks = chunkList.lengthreturn new Promise<void>((resolve, reject) => {const handler = () => {if (chunkList.length) {const chunkItem = chunkList.shift()// 直接上传二进制,不需要构造 FormData,否则上传后文件损坏service.put(chunkItem.uploadUrl, chunkItem.chunk.file, {headers: {'Content-Type': contentType}}).then(response => {if (response.status === 200) {console.log('分片:' + chunkItem.chunkNumber + ' 上传成功')successCount++// 继续上传下一个分片handler()} else {// 注意:这里没有针对失败做处理,请根据自己需求修改console.log('上传失败:' + response.status + ',' + response.statusText)}}).catch(error => {// 更新状态console.log('分片:' + chunkItem.chunkNumber + ' 上传失败,' + error)// 重新添加到队列中chunkList.push(chunkItem)handler()})}if (successCount >= totalChunks) {resolve()}}// 支持10个并发for (let i = 0; i < 10; i++) {handler()}})
}
utils/request
是对axios的封装,比如超时,返回体错误码判断等等
对应的 api/file.ts
import service from '@/utils/request'/** MD5校验 */
export const checkMd5 = (params?: object) => {return service.get('/oss/check', { params: params })
}/** 获取分片上传地址 */
export const getPartUrl = (params?: object) => {return service.get('/oss/part-url', { params: params })
}/** 分片合并 */
export const mergePart = (params?: object) => {return service.get('/oss/merge-part', { params: params, timeout: 10000 })
}
至此,分片上传即可使用
断点续传
这个其实就是在分片上传的基础做一个改进,将上传完成的分片反馈给后端做记录,再次续传时,只传对应的未上传分片即可,上传完成,再请求后端合并。
相关文章:
minio spring boot 秒传、分片上传、断点续传文件实现
此处后端使用的是前期封装的自定义starter,具体链接可参考:minio对象存储spring boot starter封装组件 这里主要针对前期封装的组件,做一个简单的应用,前端直传可查看之前的文章 秒传 秒传的逻辑比较简单,在前传上传…...
MTK平台使用Omnipeek分析空口协议讲解
讲解这个之前,我们先来了解下beacon/robe Request/Probe Response 三种帧 beacon帧 信标帧,由AP以一定的时间间隔周期性发出,以此来告诉外界自己无线网络的存在。 Beacon帧作为802.11中一个周期性的帧,Beacon周期调高,对应睡眠周期拉长,故节能(即越来休息100ms再起来…...
string和自动推断类型
欢迎来观看温柔了岁月.c的博客目前设有C学习专栏C语言项目专栏数据结构与算法专栏目前主要更新C学习专栏,C语言项目专栏不定时更新待C专栏完毕,会陆续更新C项目专栏和数据结构与算法专栏一周主要三更,星期三,星期五,星…...
【软件测试】从功能到自动化测试,测试人的进阶之路细节,这些必不可少......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 测试流程࿰…...
C语言青蛙跳台阶【图文详解】
青蛙跳台阶前言1. 题目介绍2. 解题思路3. 利用图片来演示青蛙跳台阶的原理4. 如何用C语言实现青蛙跳台阶前言 在本文,我们要与一只活泼可爱的小青蛙合作,带领着它跳上台阶,这个小家伙精力充沛,特别擅长于跳跃。我们要让它做我们的…...
笔记(五)——list容器的基础理论知识
list容器是一个双向链表容器,可以高效地进行插入删除元素,但是不能随机存取元素(不支持at()和[]操作符)。一、list容器的对象构造方法list对象采用模板类的默认构造形式例如list<T> lst;#include<iostream>…...
浅谈网络中接口幂等性设计问题
所谓幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。用数学的语言来表达就是:f(x) f(f(x))。 在数学里,幂等有两种主要的定义。 在某二元运算下,幂等元素是指被自己重复运算(或对于函数…...
《C Primer Plus》第13章复习题与编程练习
《C Primer Plus》第13章复习题与编程练习复习题1. 下面的程序有什么问题?2. 下面的程序完成什么任务?(假设在命令行环境中运行)3. 假设程序中有下列语句:4. 编写一个程序,不接受任何命令行参数或接受一个命…...
计算机SCI论文应该怎么作图? - 易智编译EaseEditing
计算机SCI论文,作图时要注意以下几个方面的问题: 1.图片的格式要tiff或者eps; 2.文件大小不能超过10M; 3.长和宽也给出了具体要求; 4.色彩模式要RGB或者灰度图; 5.文中的文字字体和大小; …...
【一】kubernetes集群部署
一、docker环境搭建 1、移除以前docker相关包 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine2、配置yam源 sudo yum install -y yum-utilssudo yum-config-manager --ad…...
Docker安装Redis
一、拉取镜像 命令::docker pull <镜像名称>:<版本号> docker pull redis 二:Docker挂载配置文件 挂载:即将宿主的文件和容器内部目录相关联,相互绑定,在宿主机内修改文件的话也随之修改容…...
在shell中执行一条可执行程序(./a.out) 系统执行的过程
目录 系统调度过程 用户空间角度: 内核角度 1、调用fork创建一个新进程 2、使用_fo_fork创建新进程 3、父进程调用wake_up_new_task尝试唤醒新进程 4、CPU选择一个合适的进程来运行; 5、运行新进程 6、实现负载均衡 系统调度过程 分析在命令行…...
【ArcGIS Pro二次开发】(10):属性表字段(field)的修改
在ArcGIS Pro中,经常会遇到用字段计算器对要素的属性表进行计算。下面以一个例子演示如何在ArcGIS Pro SDK二次开发中实现。 一、要实现的功能 如上图所示的要素图层,要实现如下功能: 当字段【市级行政区】的值为【泉州市】时,将…...
数据结构与算法—散列表
目录 散列表 散列函数 散列冲突解决 1、开放寻址法 1.1 线性探测 1.2 二次探测 1.3 双重散列 2、链表法 使用场景 单词查找 散列表与链表的结合使用LRU 散列表总结 散列表实例 散列表 Word 单词拼写功能,如何实现的?散列表(Has…...
计算机网络笔记、面试八股(一)—— TCP/IP网络模型
本章目录1. TCP/IP网络模型1.1 应用层1.1.1 应用层作用1.1.2 应用层有哪些常用协议1.2 运输层1.2.1 TCP与UDP的区别1.2.2 分块传输1.2.3 端口1.3 网络层1.3.1 IP报文1.3.2 IP地址1.3.3 网络号和主机号的获得1.3.4 子网掩码的获得1.3.5 路由1.3.6 IP地址与MAC地址的区别1.3.7 AR…...
Servlet笔记(18):国际化
三个概念 国际化: 意义着一个网站提供不同版本的翻译成访问者的语言或国籍的内容。本地化: 意味着向网站添加资源,以使其适应特定的地理或文化区域。区域设置: 针对某个国家的某个地区的设置。 Servlet可以根据请求者的区域设置…...
kibana搭建(windowslinux)
1.说明 搭建kibana方便查询es库,本文分别对windows和linux版本进行安装,因为es集群版本是7.4.1,所以配套的kibana也是选择相同版本 2.下载 https://artifacts.elastic.co/downloads/kibana/kibana-7.4.1-windows-x86_64.zip https://artifact…...
(pytorch进阶之路)Informer
论文:Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting (AAAI’21 Best Paper) 看了一下以前的论文学习学习,我也是重应用吧,所以代码部分会比较多,理论部分就一笔带过吧 论文作者也很良心的…...
关键词聚类和凸现分析-实战1——亚急性甲状腺炎的
审稿人问题第8页第26行-请指出#是什么意思,并解释为什么亚急性甲状腺炎在这里被列为#8。我认为在搜索亚急性甲状腺炎相关文章时,关键词共现分析应该提供关键词共现的数据。这些结果的实际用途是什么?亚急性甲状腺炎是一种较为罕见但重要的甲状腺疾病&am…...
二叉树——二叉搜索树中的众数
二叉搜索树中的众数 链接 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定…...
安装_配置参数解读_集群安装配置_启动选举_搭建启停脚本---大数据之ZooKeeper工作笔记004
这里首先下载zookeeper安装包,可以看到官网地址 找到download 点击下载 找到老一点的,我们找3.5.7 in the archive 点击 然后这里找到3.5.7这一个 然后下载这个-bin.tar.gz这个...
RTMP的工作原理及优缺点
一.什么是RTMP?RTMP(Real-Time Messaging Protocol,实时消息传输协议)是一种用于低延迟、实时音视频和数据传输的双向互联网通信协议,由Macromedia(后被Adobe收购)开发。RTMP的工作原理是&#…...
【数据结构与算法】——第八章:排序
文章目录1、基本概念1.1 什么是排序1.2 排序算法的稳定性1.3 排序算法的分类1.4 内排序的方法2、插入排序2.1 直接插入排序2.2 直接插入排序2.3 希尔排序3、交换排序3.1 冒泡排序3.2 快速排序4、选择排序4.1 简单选择排序4.2 树形选择排序4.3 堆排序4.4 二路归并排序5、基数排序…...
在linux中web服务器的搭建与配置
以下涉及到的linux命令大全查阅 https://www.runoob.com/linux/linux-command-manual.htmlvim命令查阅 https://www.runoob.com/linux/linux-vim.htmlscp命令https://www.runoob.com/linux/linux-comm-scp.html首先要有一个请求的服务地址用ssh 进入到linux系统中ssh 请求的服务…...
《Python机器学习》基础代码2
👂 逝年 - 夏小虎 - 单曲 - 网易云音乐 目录 👊Matplotlib综合应用:空气质量监测数据的图形化展示 🌼1,AQI时序变化特点 🌼2,AQI分布特征 相关性分析 🌼3,优化图形…...
如何基于MLServer构建Python机器学习服务
文章目录前言一、数据集二、训练 Scikit-learn 模型三、基于MLSever构建Scikit-learn服务四、测试模型五、训练 XGBoost 模型六、服务多个模型七、测试多个模型的准确性总结参考前言 在过去我们训练模型,往往通过编写flask代码或者容器化我们的模型并在docker中运行…...
9.1 IGMPv1实验
9.4.1 IGMPv1 实验目的 熟悉IGMPv1的应用场景掌握IGMPv1的配置方法实验拓扑 实验拓扑如图9-7所示: 图9-7:IGMPv1 实验步骤 (1)配置IP地址 MCS1的配置 MCS1的IP地址配置如图9-8所示: 图9-8:MCS1的配置 …...
软考高级系统分析师系列论文之十:论实时控制系统与企业信息系统的集成在通信业应用
软考高级系统分析师系列论文之十:论实时控制系统与企业信息系统的集成在通信业应用 一、摘要二、正文三、总结一、摘要 近年来,在应用需求的强大驱动下,我国通信业有了长足的进步。现有通信行业中的许多企业单位,如电信公司或移动集团,其信息系统的主要特征之一是对线路的…...
NIO与零拷贝
目录 一、零拷贝的基本介绍 二、传统IO数据读写的劣势 三、mmap优化 四、sendFile优化 五、 mmap 和 sendFile 的区别 六、零拷贝实战 6.1 传统IO 6.2 NIO中的零拷贝 6.3 运行结果 一、零拷贝的基本介绍 零拷贝是网络编程的关键,很多性能优化都离不开。 在…...
【PAT甲级题解记录】1151 LCA in a Binary Tree (30 分)
【PAT甲级题解记录】1151 LCA in a Binary Tree (30 分) 前言 Problem:1151 LCA in a Binary Tree (30 分) Tags:树的遍历 并查集 LCA Difficulty:剧情模式 想流点汗 想流点血 死而无憾 Address:1151 LCA in a Binary Tree (30 分…...
php 网站开发心得/百度搜索优化关键词排名
相同点: 都可以动态的申请并释放内存 不同点: 1. 用法不同 <1> malloc 函数为 void* malloc(size_t size), 用于申请一块长度为 size 字节的内存空间. 假如我们希望申请一个长度为 100 的 int 型数组所需的内存空间的话, 我们需要写成这样, malloc(100*sizeof(int)). 同时…...
长春火车站到中日联谊医院怎么走/站长之家怎么找网址
为什么80%的码农都做不了架构师?>>> 语法格式: select [level], column, expr... from table [where condition] start with condition connect by [prior column1 column2 | column1 prior column2]; 层次查询是通过start w…...
广告设计公司名称/重庆seo整站优化效果
实际上,百度官方已经有明确说法,不建议url中放置汉字,某些时候蜘蛛无法解析此类网址,就会影响网站的seo优化结果,详情如下: 从事SEO职业的人都知道页面URL的处理是优化过程中一个非常重要组成部分ÿ…...
网络营销方案500字/漯河seo推广
Hue版本:hue-3.9.0-cdh5.5.4 需要编译才能使用(联网) 说给大家的话:大家电脑的配置好的话,一定要安装cloudera manager。毕竟是一家人的。同时,我也亲身经历过,会有部分组件版本出现问题安装起…...
南昌网站建设收费/宣传推广文案
转载于:https://www.cnblogs.com/wangshen31/p/6792622.html...
做视频教育网站/无锡seo公司找哪家好
HTTPS和HTTP的区别主要如下: 1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。 2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。 3、http和https使用的是完全不…...