对象存储MinIO(实现文件上传、读取、下载、删除)

news/2024/4/26 23:11:45/文章来源:https://blog.csdn.net/ZHOU_VIP/article/details/129195318

一、 MinIO

        MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服

务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/

虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

        MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者

MySQL。

二、 MinIO安装和启动

       由于MinIO是一个单独的服务器,需要单独部署,有关MinIO在Windows系统上的使用请查看

以下博客。

window10安装minio_angelasp的博客-CSDN博客_win10 安装minio

三、 pom.xml(maven依赖文件)

<!-- SpringBoot Web容器 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.4</version>
</dependency>

 四、 applicatin.properties(配置文件)

# 设置单个文件大小
spring.servlet.multipart.max-file-size= 50MB
#minio文件服务器配置
s3.url=http://localhost:9000
s3.accessKey=admin
s3.secretKey=admin123
s3.bucketName=test

五、 编写Java业务类

minio涉及到的方法有:判断存储桶是否存在,创建存储桶,上传文件,读取文件、下载文件,删

除文件等操作

1、StorageProperty 存储属性类:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "s3")
public class StorageProperty {private String url;private String accessKey;private String secretKey;
//    private long callTimeOut = 60000;
//    private long readTimeOut = 300000;
}

2、minio配置类: 

import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.List;@Slf4j
@Component
@Configuration
public class MinioClientConfig {@Autowiredprivate StorageProperty storageProperty;private static MinioClient minioClient;/*** @description: 获取minioClient* @date 2021/6/22 16:55* @return io.minio.MinioClient*/public static MinioClient getMinioClient(){return minioClient;}/*** 判断 bucket是否存在** @param bucketName:*            桶名* @return: boolean* @date : 2020/8/16 20:53*/@SneakyThrows(Exception.class)public static boolean bucketExists(String bucketName) {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());}/*** 获取全部bucket** @param :* @return: java.util.List<io.minio.messages.Bucket>* @date : 2020/8/16 23:28*/@SneakyThrows(Exception.class)public static List<Bucket> getAllBuckets() {return minioClient.listBuckets();}/*** 初始化minio配置** @param :* @return: void* @date : 2020/8/16 20:56*/@PostConstructpublic void init() {try {minioClient = MinioClient.builder().endpoint(storageProperty.getUrl()).credentials(storageProperty.getAccessKey(), storageProperty.getSecretKey()).build();} catch (Exception e) {e.printStackTrace();log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());}}}

3、minio工具类 

import io.minio.*;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;@Slf4j
@Component
public class MinioUtil {/*** Minio文件上传** @param file       文件实体* @param fileName   修饰过的文件名 非源文件名* @param bucketName 所存文件夹(桶名)* @return*/public ResultEntity<Map<String, Object>> minioUpload(MultipartFile file, String fileName, String bucketName) {ResultEntity<Map<String, Object>> resultEntity = new ResultEntity();try {MinioClient minioClient = MinioClientConfig.getMinioClient();// fileName为空,说明要使用源文件名上传if (fileName == null) {fileName = file.getOriginalFilename();fileName = fileName.replaceAll(" ", "_");}InputStream inputStream = file.getInputStream();PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);return resultEntity;} catch (Exception e) {e.printStackTrace();return null;}}/*** 检查存储桶是否存在** @param bucketName 存储桶名称* @return*/public boolean bucketExists(String bucketName) {boolean flag = false;try {flag = MinioClientConfig.bucketExists(bucketName);if (flag) {return true;}} catch (Exception e) {e.printStackTrace();return false;}return false;}/*** 获取文件流** @param fileName   文件名* @param bucketName 桶名(文件夹)* @return*/public InputStream getFileInputStream(String fileName, String bucketName) {try {MinioClient minioClient = MinioClientConfig.getMinioClient();return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());} catch (Exception e) {e.printStackTrace();log.error(e.getMessage());}return null;}/*** @param bucketName:* @author* @description: 创建桶* @date 2022/8/16 14:36*/public void createBucketName(String bucketName) {try {if (StringUtils.isBlank(bucketName)) {return;}MinioClient minioClient = MinioClientConfig.getMinioClient();boolean isExist = MinioClientConfig.bucketExists(bucketName);if (isExist) {log.info("Bucket {} already exists.", bucketName);} else {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}} catch (Exception e) {e.printStackTrace();log.error(e.getMessage());}}/*** 下载文件** @param originalName 文件路径*/public InputStream downloadFile(String bucketName, String originalName, HttpServletResponse response) {try {MinioClient minioClient = MinioClientConfig.getMinioClient();InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(originalName).build());String filename = new String(originalName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);if (StringUtils.isNotBlank(originalName)) {filename = originalName;}response.setHeader("Content-Disposition", "attachment;filename=" + filename);ServletOutputStream servletOutputStream = response.getOutputStream();int len;byte[] buffer = new byte[1024];while ((len = file.read(buffer)) > 0) {servletOutputStream.write(buffer, 0, len);}servletOutputStream.flush();file.close();servletOutputStream.close();return file;} catch (Exception e) {e.printStackTrace();return null;}}/*** @param bucketName:* @description: 删除桶* @date 2022/8/16 14:36*/public void deleteBucketName(String bucketName) {try {if (StringUtils.isBlank(bucketName)) {return;}MinioClient minioClient = MinioClientConfig.getMinioClient();boolean isExist = MinioClientConfig.bucketExists(bucketName);if (isExist) {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}} catch (Exception e) {e.printStackTrace();log.error(e.getMessage());}}/*** @param bucketName:* @description: 删除桶下面所有文件* @date 2022/8/16 14:36*/public void deleteBucketFile(String bucketName) {try {if (StringUtils.isBlank(bucketName)) {return;}MinioClient minioClient = MinioClientConfig.getMinioClient();boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());if (isExist) {minioClient.deleteBucketEncryption(DeleteBucketEncryptionArgs.builder().bucket(bucketName).build());}} catch (Exception e) {e.printStackTrace();log.error(e.getMessage());}}/*** 根据文件路径得到预览文件绝对地址** @param bucketName* @param fileName* @return*/public String getPreviewFileUrl(String bucketName, String fileName) {try {MinioClient minioClient = MinioClientConfig.getMinioClient();return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).build());} catch (Exception e) {e.printStackTrace();return "";}}
}

 六、 MinIoController

文件上传、文件读取、文件下载、文件删除接口如下:


@RestController
@RequestMapping("/minio")
public class MinIoController extends BaseController {MinioUtil minioUtil = new MinioUtil();/*** 上传文件* @param file* @return*/@PostMapping("/uploadFile")public AjaxResult uploadFile(@RequestBody MultipartFile file) {MinioClient minioClient = MinioClientConfig.getMinioClient();if (minioClient == null) {return AjaxResult.error("连接MinIO服务器失败", null);}ResultEntity<Map<String, Object>> result = minioUtil.minioUpload(file, "", "data-enpower");if (result.getCode() == 0) {return AjaxResult.success("上传成功");} else {return AjaxResult.error("上传错误!!!");}}/*** 获取文件预览地址* @param fileName* @return*/@RequestMapping("/getRedFile")public AjaxResult getRedFile(@RequestBody String fileName) {MinioClient minioClient = MinioClientConfig.getMinioClient();if (minioClient == null) {return AjaxResult.error("连接MinIO服务器失败", null);}String url = minioUtil.getPreviewFileUrl("data-enpower",fileName);return AjaxResult.success(url);}/*** 下载文件* @param fileName* @param response* @return*/@RequestMapping("/downloadFile")public String downloadFile(@RequestParam String fileName, HttpServletResponse response) {MinioClient minioClient = MinioClientConfig.getMinioClient();if (minioClient == null) {return "连接MinIO服务器失败";}return minioUtil.downloadFile("data-enpower",fileName,response) != null ? "下载成功" : "下载失败";}/*** 删除文件** @param fileName 文件路径* @return*/@PostMapping("/deleteFile")public String deleteFile(String fileName) {MinioClient minioClient = MinioClientConfig.getMinioClient();if (minioClient == null) {return "连接MinIO服务器失败";}boolean flag = minioUtil.deleteFile("data-enpower",fileName);return flag == true ? "删除成功" : "删除失败";}}

对象存储MinIO基本用法

对象存储服务MinIO的基本用法 

https://www.cnblogs.com/hackyle/p/minio-demo.html

 

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

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

相关文章

教你用反射机制如何几分钟搭建完后端

如果想快速搭建后台跨域使用这些技术 反射mybatis-plusjson 反射可以实现动态数据的传输 一般对数据库进行操作肯定离不开这些代码 如果我们用反射机制只需要这一个就行 而说到反射的好处&#xff0c;一般情况下我们做增删改查需要大量的接口才能完成&#xff0c;而用反射我…

通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作

1.通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输入led…

LabVIEW主VI前面板中显示或使用多个子VI

LabVIEW主VI前面板中显示或使用多个子VI想在程序中连接一个或多个子VI的前面板&#xff0c;但是当调用它们时&#xff0c;每个子VI在计算机屏幕上显示为一个新窗口。那么怎么能让每个子VI作为主VI前面板的一部分进行显示&#xff0c;而不是在屏幕上显示多个窗口&#xff1f;正在…

Malware Dev 00 - Rust vs C++ 初探

写在最前 如果你是信息安全爱好者&#xff0c;如果你想考一些证书来提升自己的能力&#xff0c;那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里&#xff1a; https://discord.gg/9XvvuFq9Wb我会提供备考过程中尽可能多的帮助&#xff0c;并分享学习和实践过程…

mysql 内存架构

1. 背景 从 innodb 的整体架构中可以知道 innodb 的内存架构中分为 buffer pool 缓存区, change pool 修改缓冲区, adaptive hash index 自适应哈希索引, 和 log buffer 日志缓冲区. 2. buffer pool buffer pool 是用于缓冲磁盘页的数据&#xff0c;mysql 的80%的内存会分配给…

GroupDocs.Merger for Java

GroupDocs.Merger for Java GroupDocs.Merger for Java是一个文档操作API&#xff0c;可帮助您合并、拆分、交换或删除文档页面。API通过启用或禁用密码提供保护&#xff0c;并允许开发人员加入PDF、Microsoft Word、Excel和Powerpoint文档。 支持的文件格式 Microsoft Office格…

内存管理框架---Slab(二)

站在Arnold Lu南京大佬的肩膀&#xff0c;俯瞰内存管理之slab 文章目录slab层的由来slab/slub/slobslab层的设计思想slab相关数据结构创建slab描述符分配slab对象释放slab对象销毁缓存在内核栈上的静态分配高端内存的映射永久映射临时映射每个CPU的分配新的每个CPU接口编译时的…

为什么需要这个岗位,软件测试是干什么

目录 一、软件测试概念 二、软件测试目的 三、软件测试基本原则 四、软件测试主要工作内容 五、软件测试方法 六、测试工程师的职责 七、为什么要软件测试这个岗位 一、软件测试概念 软件测试&#xff1a;为了发现软件错误和缺陷&#xff08;统称bug&#xff09;而执行…

浅谈liunx init.d 和 rc.local 两种起动方式

浅谈liunx init.d 和 rc.local 两种起动方式 以rabbitmq 举例 &#xff08;一&#xff09;.init.d 方式 开机自动重启设置 1.在/etc/init.d 目录下新建一个 rabbitmq [rootlocalhost init.d]# vi rabbitmq具体脚本如下所示&#xff1a; #!/bin/bash # # chkconfig: 2345 …

全球智慧能源解决方案服务商「雄韬股份」牵手企企通,谱写采购数字化变革之路

近日&#xff0c;全球知名智慧能源解决方案服务商「深圳市雄韬电源科技股份有限公司」&#xff08;以下简称“雄韬股份”&#xff09;与企企通达成合作。本次合作&#xff0c;企企通将为雄韬股份提供专业的采购数字化解决方案&#xff0c;推动企业采购更加智能、高效、透明&…

计算机网络(2)从十六进制的ip数据报中得到详细字段信息

本博文介绍如何将十六进制的ip报文拆分出具体的字段信息。社会计算机网络和网络协议分析的初学者参考&#xff08;今天看了网络协议分析期末复习重点的最后一个大题&#xff0c;竟然一头雾水&#xff0c;然后快马加鞭翻阅各种资料&#xff0c;然后差不多学会 了&#xff09;wir…

浏览器输入www.baidu.com后执行的全部过程

日升时奋斗&#xff0c;日落时自省 <1>URL输入 URL称为 : 统一资源定位符,用于定位互联网上的资源,也就是平常提起的"网址" 地址栏输入网址之后按下回车,浏览器会对输入的信息进行评判 (1)检查输入的内容是否是是一个合法的网址连接(非法地址不行) (2)合法的…

Python Unittest框架

1、unittest简介 unittest是Python自带的单元测试框架,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件,主要适用于单元测试,可以用来作自动化测试框架的用例组织执行框架。 2、unittest框架的特性: 提供用例组织与执行:当测试用例只有几条的时候可以不考虑…

Nginx 02篇——Nginx基本配置与参数说明篇

Nginx 02篇——Nginx基本配置与参数说明篇前言-默认配置文件1. 前言——关于nginx1.1 关于nginx1. 2 Nginx 01篇——Nginx安装2. Nginx 配置文件结构2.1 Nginx 安装后的默认文件2.2 Nginx 的三大组成部分3. 配置参说明-1——整个配置3.1 配置说明3.2 参考4. 配置说明-2—详细说…

postgres 源码解析51 LWLock轻量锁--2

本篇将着重讲解LWLock涉及的主要API工作流程与实现原理&#xff0c;相关基础知识见回顾&#xff1a;postgres 源码解析50 LWLock轻量锁–1 API介绍 函数API功能CreateLWLocks分配LWLocks所需的内存并进行初始化LWLockNewTrancheId分配新的Tranche ID,供用户使用Extension模块…

结构效度分析流程

结构效度分析流程如下图 一、结构效度的意义 效度分析在学术研究中非常常见&#xff0c;结构效度是为了分析“从量表获得的结果与设计该量表时所假定的理论之间的符合程度”。简单来讲&#xff0c;在研究者设计量表之初&#xff0c;一般会预设好几个维度&#xff0c;在经过因子…

kafka入门到精通

文章目录一、kafka概述&#xff1f;1.定义1.2消息队列1.2.1 传统消息队列的使用场景1.2.2 消息队列好处1.2.3 消息队列两种模式1.3 kafka基础架构二、kafka快速入门1.1使用docker-compose安装kafka1.2测试访问kafka-manager1.3 查看kafka版本号1.4 查看zookeeper版本号1.5 扩展…

python学习之OpenCV-Python模块的部分应用示例(生成素描图和动漫图)

文章目录前言一、图片转灰度二、对图片进行二值化处理三、对图片去除噪点四、调整图片透明度五、生成素描滤镜效果图&#xff08;方法结合应用&#xff09;六、生成动漫卡通滤镜效果图&#xff08;方法结合应用&#xff09;总结前言 OpenCV 是一个图像和视频处理库&#xff0c…

掌握饮食健康:了解你的宏量营养素摄入

谷禾健康 // 俗话说“病从口入”&#xff0c;我们的健康状况很大一部分取决于饮食。而食物基本上是由各种营养素构成的。 宏量营养素是人体大量需要的必需营养成分。宏量营养素指的是“三大”营养素&#xff1a;蛋白质、脂肪和碳水化合物&#xff0c;它们是我们饮食中的关键。 …

【JavaScript】基本语法大全

前言&#xff1a; 大家好&#xff0c;我是程序猿爱打拳。在学习C和Java这样的后端编程语言后&#xff0c;我们大概率会学习一些关于前端的语言如HTMLJavaScript。又因为前后端基本语法有些许不同&#xff0c;因此我整理出来。今天给大家讲解的是JS中的数据类型、运算符、选择结…