Spring项目如何通过MinIO实现文件分片上传、断点续传、秒传

devtools/2024/9/23 17:01:50/

一、前端

前端将文件分成固定大小的若干个,在Vue前端,可以使用File API和Blob对象将文件分片

// 分片上传函数
async function uploadFile(file) {const chunkSize = 5 * 1024 * 1024; // 5MB每片const totalChunks = Math.ceil(file.size / chunkSize);for (let i = 0; i < totalChunks; i++) {const start = i * chunkSize;const end = Math.min(start + chunkSize, file.size);const chunk = file.slice(start, end);// 逐个上传分片await uploadChunk(chunk, i, totalChunks);}
}// 上传分片函数
async function uploadChunk(chunk, chunkIndex, totalChunks) {const formData = new FormData();formData.append('chunk', chunk);formData.append('chunkIndex', chunkIndex);formData.append('totalChunks', totalChunks);await fetch('/api/upload', {method: 'POST',body: formData});
}
二、后端
1、分片上传

前端每一个分片通过调用upload接口上传,每个片段有个索引index

import io.minio.MinioTemplate;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;@RestController
@RequestMapping("/api")
public class FileUploadController {@Autowiredprivate MinioTemplate minioTemplate;private final String BUCKET_NAME = "your-bucket-name";@PostMapping("/upload")public String uploadChunk(@RequestParam("chunk") MultipartFile chunk,@RequestParam("chunkIndex") int chunkIndex,@RequestParam("totalChunks") int totalChunks) {try {// 保存分片到本地或临时存储String chunkFileName = "file_part_" + chunkIndex;InputStream inputStream = chunk.getInputStream();// 将分片上传到MinIOminioTemplate.putObject(BUCKET_NAME, chunkFileName, inputStream, chunk.getSize());// 如果所有分片上传完毕,进行合并if (chunkIndex == totalChunks - 1) {mergeChunks(totalChunks);}return "Chunk uploaded successfully";} catch (Exception e) {e.printStackTrace();return "Upload failed";}}
}
2、分片合并

逐个分片上传完成之后,调用这个方法进行合并

private void mergeChunks(int totalChunks) {// 合并逻辑try {String mergedFileName = "merged_file"; // 合并后文件名// 准备分片列表List<ComposeSource> sources = new ArrayList<>();for (int i = 0; i < totalChunks; i++) {sources.add(ComposeSource.builder().bucket(BUCKET_NAME).object("file_part_" + i).build());}// 调用MinIO合并接口minioTemplate.composeObject(BUCKET_NAME, mergedFileName, sources);} catch (Exception e) {e.printStackTrace();}
}
3、断点续传
@GetMapping("/check")
public List<Integer> checkUploadedChunks(@RequestParam String fileMd5) {List<Integer> uploadedChunks = new ArrayList<>();try {// 检查存储中是否存在分片for (int i = 0; i < totalChunks; i++) {String chunkFileName = "file_part_" + i;if (minioTemplate.isObjectExist(BUCKET_NAME, chunkFileName)) {uploadedChunks.add(i);}}} catch (Exception e) {e.printStackTrace();}return uploadedChunks;
}
4、秒传

根据生成对应的md5,和minIO中的文件的MD5去对比,如果存在,直接返回域名加路径即可,不存在再执行上传

// 检查文件是否已上传
@GetMapping("/check")
public boolean checkFile(@RequestParam String fileMd5) {try {// 查询MinIO是否存在对应的文件return minioTemplate.isObjectExist(BUCKET_NAME, fileMd5);} catch (Exception e) {e.printStackTrace();return false;}
}


 


http://www.ppmy.cn/devtools/116093.html

相关文章

go语言 结构体

结构体类型别名和自定义类型 自定义类型 类型别名结构体创建结构体实例访问结构体字段修改结构体字段嵌套结构体结构体方法结构体内存布局 空结构体 题 关于 range 循环的陷阱构造函数方法 和 接收者定义方法 什么时候应该使用指针类型接收者任意类型添加方法 结构体的匿名字段…

RISC-V交叉编译器下载

1 Ubuntu 20.04版 riscv64-unknown-elf-gcc&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1H1WQjQGLlT-xfg3-HWCu3Q 提取码&#xff1a;w2wnriscv64-unknown-linux-gnu-gcc&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1gkQDEYokTy1pjDbY15NYRg 提取码&#…

SQL Server全方位指南:从入门到高级详解

本文将分为三大部分&#xff0c;逐步深入SQL Server的基础知识、进阶技巧和高级特性&#xff0c;旨在帮助从初学者到经验丰富的开发人员深入理解和使用SQL Server。 一、入门篇 1.1 什么是SQL Server&#xff1f; SQL Server 是由微软开发的关系型数据库管理系统&#xff08…

Pandas -----------------------基础知识(二)

dataframe读写数据操作 import pandas as pd# 准备数据(字典) data [[1, 张三, 1999-3-10, 18],[2, 李四, 2002-3-10, 15],[3, 王五, 1990-3-10, 33],[4, 隔壁老王, 1983-3-10, 40] ]df pd.DataFrame(data, columns[id, name, birthday, age]) df写到csv文件中 &#xff0c;…

数据结构 - 概述及其术语

经过上一章节《数据结构与算法之间有何关系&#xff1f;》的阐述&#xff0c;相信大家对数据结构多少有了点了解&#xff0c;今天我们将进入数据结构的正式学习中。 在计算机科学中&#xff0c;数据结构是一种数据管理、组织和存储的格式。它是相互之间存在一种或多种特定关系的…

【计算机网络】初识网络

初识网络 初识网络网络的发展局域网广域网 网络基础IP地址端口号协议五元组协议分层OSI 七层模型TCP/IP五层模型封装和分用"客户段-服务器"结构 初识网络 网络的发展 在过去网络还没有出现的时候, 我们的计算机大部分都是独自运行的, 比如以前那些老游戏, 都是只能…

線上測試代理IP詳細教程

在使用代理IP之前&#xff0c;進行線上測試是非常必要的。以下是幾種主要原因&#xff1a; 驗證代理IP的有效性&#xff1a;有些代理IP可能已經失效&#xff0c;無法正常使用。通過測試&#xff0c;可以確保代理IP是有效的。檢查匿名性&#xff1a;不同的代理IP提供不同級別的…

假期学习笔记总结--iOS 自动释放池

iOS 自动释放池 https://juejin.cn/post/6844904094503567368#heading-23 ARC和MRC 苹果在 iOS 5 中引入了ARC&#xff08;Automatic Reference Counting&#xff09;自动引用计数内存管理技术&#xff0c;通过LLVM编译器和Runtime协作来进行自动管理内存。LLVM编译器会在编…