微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)

🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍

文章目录

        1.0 MinIO 文件服务器概述

        1.1 MinIO 使用 Docker 部署

        1.2 MinIO 控制台的使用

        2.0 使用 Java 操作 MinIO

        3.0 使用 minioClient 对象的方法

        3.1 判断桶是否存在

        3.2 创建桶

        3.3 删除桶

        3.4 删除桶内的对象

        3.5 获取 url

        3.6 上传文件

        3.7 下载文件

        3.8 获取所有桶

        3.9 获取所有桶名

        3.10 获取指定桶中的所有对象

        4.0 MinIO 工具类


        1.0 MinIO 文件服务器概述

        MinIO 是一个高性能的对象存储服务器,专门设计用来处理大规模的非结构化数据。它提供

与 Amazon S3(简单存储服务)兼容的 API,使得开发人员和运维团队能够轻松实现数据存储和

管理。以下是 MinIO 的一些关键特点和概述:

        1)高性能:MinIO 具有极高的吞吐量,能够支持大规模的并发请求,适用于需要快速处理大

量数据的应用场景,如机器学习和数据分析等。

        2)易于部署:MinIO 可以在多种环境中部署,包括本地服务器、虚拟机、容器(如 Docker

和 Kubernetes)以及云环境,以灵活适应不同的使用需求。

        3)兼容 S3 API:MinIO 采用与 S3 兼容的 API,这意味着用户可以使用现有的 S3 工具和软

件与 MinIO 进行交互,降低了迁移和集成的门槛。

        4)数据保护:MinIO 支持多种数据冗余和保护机制,包括纠删码(Erasure Coding),可以

在发生硬件故障时保护数据的完整性。

        5)安全性:MinIO 提供多种安全措施,包括身份验证、访问控制、TLS 加密等,确保数据在

传输和存储过程中的安全。

        6)企业级功能:MinIO 具备多租户支持、审计日志、生命周期管理等功能,适合企业和组织

使用。

        7)开源:MinIO 是一个开源项目,允许社区参与贡献和改进,同时也提供商业支持选项,适

合不同规模的企业使用。

MinIO 官网:MinIO | S3 Compatible Storage for AI

        在以往的项目中,用的比较多的是 OSS 服务有腾讯云、阿里云的存储服务,但是这些云存储

的服务大多数都是要收取一定的费用,一直积累起来也是一笔不小的费用。因此,自己部署一台

MinIO 文件服务器是一种不错的选择。

        1.1 MinIO 使用 Docker 部署

        1)执行以下命令进行部署:

docker run \-p 9000:9000 \-p 9001:9001 \--name minio \-v root\minio\data:/data \-e "MINIO_ROOT_USER=xbs12345" \-e "MINIO_ROOT_PASSWORD=xbs12345" \quay.io/minio/minio server /data --console-address ":9001"

        docker run:表示启动运行容器。

        -p:表示为容器绑定一个本地的端口。

        --name:表示为容器创建一个本地的名字。

        -v:表示将文件路径设置为容器使用持久卷位置。将数据保存到本地,使其能够在容器重启时保持持久化。

        -e:设置账号秘密。

        其中访问控制台的端口为:9001,api 的访问端口为:9000 。

        2)服务端部署完毕之后,通过控制台访问服务器:

访问 MinIO 控制台:

        http://自己的IP地址:9001

        1.2 MinIO 控制台的使用

        在对象存储服务里面,所有的文件都是以桶的形式来组织的。简单说,可以将桶看作是目

录,这个目录下有很多的文件或者文件夹,这和其它云存储服务基本一致。

首先需要创建桶:

        接着,设置桶名:

        桶这就创建好了:

        默认创建的存储桶,均为私有桶,无法被公开访问,需要设置成公开:

        通常而言,要将数据写入操作进行控制;而读操作,很多不涉及安全问题,希望能被互联网

公开访问,以便加快文件的访问速度。

        可以在存储桶里面配置,将数据读取权限设置为公开访问:

        测试上传图片:

        选择 Upload: 

        上传成功: 

        接着通过:http//自己的IP地址:9000/text/R-C (2).jpg 来访问,此时 "/text/R-C (2).jpg" 是桶

名与文件名的拼接。

        最后访问到已经上传的图片了:

        2.0 使用 Java 操作 MinIO

        1)首先引入依赖:

        <!-- 操作minio的java客户端--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.2</version></dependency>

        2)获取 API 访问凭证:

        生成密钥之后,需要记住这对密钥,最好保存起来。 

        3)在 application.yaml 中配置 MinIo:

#minio配置
spring:minio:access-key: xxxxxsecret-key: xxxxxurl: http://xxxxx:9000  #访问地址bucket-name: xbs

        将之前的密钥配置到该配置文件中,url 是 MinIO 的服务器地址,bucket-name 是表示对具

体某一个桶进行操作

        4)设置配置类:

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Data
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioConfig {private String accessKey;private String secretKey;private String url;private String bucketName;@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(url).credentials(accessKey,secretKey).build();}
}

        通过 @ConfigurationProperties(prefix = "spring.minio") 注解,将配置文件中的参数映射

到当前类中的对应的属性中,通过 @Configuration 注解,将 minioClient 实体对象添加到

Spring IOC容器中。

        接下来,就可以使用 minioClient 实体对象中的方法,对文件进行操作,如上传文件到

MinIO服务器中、从 MinIO 服务器中下载文件、删除 MinIO 服务器中的文件等等。

        3.0 使用 minioClient 对象的方法

        3.1 判断桶是否存在

代码如下:

    @Autowiredprivate MinioClient minioClient;/*** 判断bucket是否存在,不存在就创建* @param bucketName bucket名称* @return 成功返回true,否则返回false*/public boolean exitBucket(String bucketName){try {//判断bucket是否存在BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();boolean isExist = minioClient.bucketExists(bucketExistsArgs);if (isExist){return true;}//不存在的话,则创建bucketMakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();minioClient.makeBucket(makeBucketArgs);return true;}catch (Exception e){e.printStackTrace();log.info("minio 连接失败");return false;}}

        根据桶名,来判断该桶是否存在 MinIO 中。

测试:

    @Testpublic void test() throws Exception {BucketExistsArgs build = BucketExistsArgs.builder().bucket("xbs").build();boolean b = minioClient.bucketExists(build);if (b){System.out.println("该桶存在");}}

执行结果:

        3.2 创建桶

代码如下:

    /*** 创建bucket* @param bucketName bucket名称* @return 成功创建返回true,否则返回false*/public boolean makeBucket(String bucketName){try {MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();minioClient.makeBucket(makeBucketArgs);}catch (Exception e){e.printStackTrace();log.info("桶创建失败");return false;}return true;}

        参数就只有一个,在 MinIO 服务器中创建 bucketName 的桶。

测试:

    @Testpublic void makeBucket() throws Exception {boolean xbs = minioUtils.makeBucket("hero");if (xbs){System.out.println("创建成功");return;}System.out.println("创建失败");}

执行结果:

        3.3 删除桶

代码如下:

    /*** 根据桶名删除* @param bucketName 桶名* @return 删除成功返回true,否则返回false*/public boolean removeBucket(String bucketName){try {RemoveBucketArgs removeBucketArgs = RemoveBucketArgs.builder().bucket(bucketName).build();minioClient.removeBucket(removeBucketArgs);}catch (Exception e){e.printStackTrace();log.info("桶删除失败");return false;}return true;}

        直接根据桶名来删除。

测试:

    @Testpublic void removeBucket() throws Exception {boolean hero = minioUtils.removeBucket("hero");if (hero){System.out.println("删除成功");return;}System.out.println("删除失败");}

执行结果:

        需要注意的是,当桶不为空,则删除桶失败。

测试:

        3.4 删除桶内的对象

代码如下:

    /*** 根据桶名、对象名来删除一个对象* @param bucketName 桶名* @param objectName 对象名* @return 删除成功返回true,否则返回false* @throws Exception*/public boolean removeObject(String bucketName, String objectName) throws Exception {try {RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build();minioClient.removeObject(removeObjectArgs);return true;}catch (Exception e) {e.printStackTrace();log.info("删除失败");return false;}}

        参数有两个,一个是桶名、另一个是对象名。根据桶名和对象名,可以确定删除的对象。这

里说的对象名,可以理解为文件名。

测试:

    @Testpublic void removeObject() throws Exception {boolean xbs = minioUtils.removeObject("text", "R-C (2).jpg");if (xbs){System.out.println("删除成功");return;}System.out.println("删除失败");}

执行结果:

        这就删除成功了。

        除了可以一个一个删除,也可以进行批量删除:

代码如下:

    /*** 删除指定桶的多个文件对象,返回删除错误的对象列表,全部删除成功,返回空列表** @param bucketName  存储桶名称* @param objectNames 含有要删除的多个object名称的迭代器对象* @return* eg:* List<DeleteObject> objects = new LinkedList<>();* objects.add(new DeleteObject("my-objectname1"));* objects.add(new DeleteObject("my-objectname2"));* objects.add(new DeleteObject("my-objectname3"));**/public List<String> removeObjects(String bucketName, List<DeleteObject> objectNames) throws Exception {List<String> deleteErrorNames = new ArrayList<>();try {RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder().bucket(bucketName).objects(objectNames).build();Iterable<Result<DeleteError>> results = minioClient.removeObjects(removeObjectsArgs);for (Result<DeleteError> result : results) {DeleteError deleteError = result.get();deleteErrorNames.add(deleteError.objectName());}return deleteErrorNames;}catch (Exception e) {e.printStackTrace();log.info("删除失败");return null;}}

        3.5 获取 url

        当上传完照片之后,需要拿到可以访问到该照片的 url:

代码如下:

    /*** 获取url* @param bucketName 桶名* @param objectName 对象名* @param time 限制时间* @param unit 时间单位* @return 找不到返回null,找到返回对象的url*/public String getUrl(String bucketName, String objectName, int time, TimeUnit unit){try {GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectName).expiry(time, unit).build();return minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);}catch (Exception e){e.printStackTrace();log.info("获取url失败");return null;}}

        具体的参数有三个,桶名、对象名和设置过期时间。顾名思义,当超过了过期时间后,访问

图片失败。

测试:

    @Testpublic void getUrl() throws Exception{String xbs = minioUtils.getUrl("xbs", "v2-44a694ce65533da4b79b96a003acbbc7_r.jpg", 10, TimeUnit.SECONDS);System.out.println(xbs);}

执行结果:

        得到 url 后,可以直接访问:

        当超过 10 秒后,再次访问:

        时间过期了,就访问不了。

        3.6 上传文件

代码如下:

    /*** 上传文件* @param file 需要上传的文件* @param fileName 文件在桶中的命名* @param bucketName 需要上传的桶名* @return 上传成功返回true,否则返回false*/public boolean upload(MultipartFile file,String fileName,String bucketName){try {InputStream fileInputStream = file.getInputStream();PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName+file.getName().substring(file.getName().lastIndexOf("."))).stream(fileInputStream, file.getSize(), -1).contentType(file.getContentType()).build();minioClient.putObject(putObjectArgs);}catch (Exception e){e.printStackTrace();log.info("上传失败");return false;}return true;}

解析核心代码:

        1)首先,设置目标存储桶的名称为 bucketName。

        2)构建对象名称:fileName: 用户自定义的文件名前缀。

file.getName().substring(file.getName().lastIndexOf(".")): 获取原始文件的扩展名(从最后一个

点开始截取)。最终的对象名称是由 fileName 和文件扩展名拼接而成,确保上传后的文件名包含

正确的扩展名。

        3)fileInputStream: 文件的输入流,用于读取文件内容并上传到 MinIO。

file.getSize(): 文件的大小(以字节为单位),告诉 MinIO 文件的实际大小。

-1: 表示未知的分段大小(part size),MinIO 会根据文件大小自动处理分段上传。

        4)设置文件的内容类型(MIME 类型),例如 image/jpeg、application/pdf 等,这有助于

客户端正确解析下载的文件。

测试:

    @Testpublic void upload() throws Exception {// 创建一个 MockMultipartFile 实例来模拟图片文件String fileName = "1111.jpg";String contentType = "image/jpg";Path path = Paths.get("D:\\照片\\1111.jpg"); // 假设图片文件在目录下byte[] content = Files.readAllBytes(path);MultipartFile file = new MockMultipartFile(fileName, fileName, contentType, content);boolean xbs = minioUtils.upload(file, "4", "xbs");if (xbs){System.out.println("上传成功");}}

执行结果: 

        上传成功了。

        除了这种上传方式,还有一种是直接根据文件路径进行上传:

代码如下:

    /*** 上传文件* @param bucketName 桶名* @param objectName 对象名* @param fileName 文件路径* @return 上传成功返回true,否则返回false* @throws Exception*/public boolean uploadObject(String bucketName, String objectName, String fileName) throws Exception {try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build();minioClient.uploadObject(uploadObjectArgs);log.info("上传成功");return true;}catch (Exception e){e.printStackTrace();log.info("上传失败");return false;}}

        有三个简单的参数,桶名、需要上传文件的路径、上传文件之后在桶中的命名。

        3.7 下载文件

代码如下:

    /*** 下载文件* @param bucketName 桶名* @param objectName 目标下载对象* @return 下载成功返回true,否则返回false* @throws IOException*/public boolean download(String bucketName,String objectName) throws IOException {InputStream inputStream = null;OutputStream outputStream = null;try {GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket(bucketName).object(objectName).build();inputStream = minioClient.getObject(getObjectArgs);File file = new File("D:/Download/" + objectName);outputStream = new FileOutputStream(file);IOUtils.copy(inputStream,outputStream);}catch (Exception e){e.printStackTrace();log.info("下载失败");return false;}finally {try {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}} catch (Exception e) {e.printStackTrace();}}return true;}

        根据桶名、对象名来选中需要下载的文件,接着通过获取输入流之后拷贝到输出流中。从而

完成文件下载。

测试:

    @Testpublic void download() throws Exception{boolean xbs = minioUtils.download("xbs", "1.jpg");if (xbs){System.out.println("下载成功");return;}System.out.println("下载失败");}

执行结果:

        这就下载成功了。

        除了这种下载方式,还有另一个下载方式:

代码如下:

    /*** 下载文件* @param bucketName 桶名* @param objectName 对象名* @param fileName 下载到本地路径* @return* @throws Exception*/public boolean downloadObject(String bucketName, String objectName, String fileName) throws Exception {try {DownloadObjectArgs downloadObjectArgs = DownloadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build();minioClient.downloadObject(downloadObjectArgs);log.info("下载成功");return true;}catch (Exception e) {e.printStackTrace();log.info("下载失败");return false;}}

        直接给定三个参数:桶名、对象名、下载路径就可以完成下载文件。

        3.8 获取所有桶

代码如下:

    /*** 获取所有桶* @return 桶集合*/public List<Bucket> getAllBuckets(){List<Bucket> buckets = null;try {buckets = minioClient.listBuckets();}catch (Exception e){e.printStackTrace();log.info("获取桶失败");return null;}return buckets;}

测试:

    @Testpublic void getBucket(){List<Bucket> allBuckets = minioUtils.getAllBuckets();for (Bucket bucket : allBuckets) {System.out.println("bucket.name() = " + bucket.name());System.out.println("bucket.creationDate() = " + bucket.creationDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));}}

执行结果:

        3.9 获取所有桶名

代码如下:

    /*** 获取所有桶名* @return 桶名集合*/public List<String> getAllBucketNames(){List<Bucket> allBuckets = getAllBuckets();List<String> collect = null;if (CollUtil.isNotEmpty(allBuckets)){collect = allBuckets.stream().map(Bucket::name).collect(Collectors.toList());}return collect;}

测试:

    @Testpublic void getAllBucketNames() throws Exception {List<String> bucketNames = minioUtils.getAllBucketNames();if (CollUtils.isNotEmpty(bucketNames)) {System.out.println(bucketNames);}}

执行结果:

        3.10 获取指定桶中的所有对象

代码如下:

    /*** 获取桶内所有对象* @param bucketName 桶名* @return 返回对象集合*/public Iterable<Result<Item>> listObjects(String bucketName){try {ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder().bucket(bucketName).build();return minioClient.listObjects(listObjectsArgs);}catch (Exception e){e.printStackTrace();log.info("获取桶失败");return null;}}

        唯一的参数就是桶名,根据桶名来查询当前桶中的所有对象。

测试:

    @Testpublic void listObjects() throws Exception {Iterable<Result<io.minio.messages.Item>> listObjects = minioUtils.listObjects("xbs");for (Result<io.minio.messages.Item> itemResult : listObjects) {Item item = itemResult.get();System.out.println("item.getSize() = " + item.size());System.out.println("item.getObjectName() = " + item.objectName());}}

执行结果:

        4.0 MinIO 工具类

        通过以上的方法可以解决绝大部分的场景应用了,可以将这些的方法封装成一个 MinIO 的

工具类。

代码如下:

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import com.hmall.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;@Component
@Slf4j
//关于minio的工具
public class MinioUtils {@Autowiredprivate MinioConfig minioConfig;@Autowiredprivate MinioClient minioClient;/*** 判断bucket是否存在,不存在就创建* @param bucketName bucket名称* @return 成功返回true,否则返回false*/public boolean exitBucket(String bucketName){try {//判断bucket是否存在BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();boolean isExist = minioClient.bucketExists(bucketExistsArgs);if (isExist){return true;}//不存在的话,则创建bucketMakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();minioClient.makeBucket(makeBucketArgs);return true;}catch (Exception e){e.printStackTrace();log.info("minio 连接失败");return false;}}/*** 创建bucket* @param bucketName bucket名称* @return 成功创建返回true,否则返回false*/public boolean makeBucket(String bucketName){try {MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();minioClient.makeBucket(makeBucketArgs);}catch (Exception e){e.printStackTrace();log.info("桶创建失败");return false;}return true;}/*** 根据桶名删除* @param bucketName 桶名* @return 删除成功返回true,否则返回false*/public boolean removeBucket(String bucketName){try {RemoveBucketArgs removeBucketArgs = RemoveBucketArgs.builder().bucket(bucketName).build();minioClient.removeBucket(removeBucketArgs);}catch (Exception e){e.printStackTrace();log.info("桶删除失败");return false;}return true;}/*** 根据桶名、对象名来删除一个对象* @param bucketName 桶名* @param objectName 对象名* @return 删除成功返回true,否则返回false* @throws Exception*/public boolean removeObject(String bucketName, String objectName) throws Exception {try {RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build();minioClient.removeObject(removeObjectArgs);return true;}catch (Exception e) {e.printStackTrace();log.info("删除失败");return false;}}/*** 删除指定桶的多个文件对象,返回删除错误的对象列表,全部删除成功,返回空列表** @param bucketName  存储桶名称* @param objectNames 含有要删除的多个object名称的迭代器对象* @return* eg:* List<DeleteObject> objects = new LinkedList<>();* objects.add(new DeleteObject("my-objectname1"));* objects.add(new DeleteObject("my-objectname2"));* objects.add(new DeleteObject("my-objectname3"));**/public List<String> removeObjects(String bucketName, List<DeleteObject> objectNames) throws Exception {List<String> deleteErrorNames = new ArrayList<>();try {RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder().bucket(bucketName).objects(objectNames).build();Iterable<Result<DeleteError>> results = minioClient.removeObjects(removeObjectsArgs);for (Result<DeleteError> result : results) {DeleteError deleteError = result.get();deleteErrorNames.add(deleteError.objectName());}return deleteErrorNames;}catch (Exception e) {e.printStackTrace();log.info("删除失败");return null;}}/*** 获取url* @param bucketName 桶名* @param objectName 对象名* @param time 限制时间* @param unit 时间单位* @return 找不到返回null,找到返回对象的url*/public String getUrl(String bucketName, String objectName, int time, TimeUnit unit){try {GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectName).expiry(time, unit).build();return minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);}catch (Exception e){e.printStackTrace();log.info("获取url失败");return null;}}/*** 上传文件* @param file 需要上传的文件* @param fileName 文件在桶中的命名* @param bucketName 需要上传的桶名* @return 上传成功返回true,否则返回false*/public boolean upload(MultipartFile file,String fileName,String bucketName){try {InputStream fileInputStream = file.getInputStream();PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName+file.getName().substring(file.getName().lastIndexOf("."))).stream(fileInputStream, file.getSize(), -1).contentType(file.getContentType()).build();minioClient.putObject(putObjectArgs);}catch (Exception e){e.printStackTrace();log.info("上传失败");return false;}return true;}/*** 上传文件* @param bucketName 桶名* @param objectName 对象名* @param fileName 文件路径* @return 上传成功返回true,否则返回false* @throws Exception*/public boolean uploadObject(String bucketName, String objectName, String fileName) throws Exception {try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build();minioClient.uploadObject(uploadObjectArgs);log.info("上传成功");return true;}catch (Exception e){e.printStackTrace();log.info("上传失败");return false;}}/*** 下载文件* @param bucketName 桶名* @param objectName 目标下载对象* @return 下载成功返回true,否则返回false* @throws IOException*/public boolean download(String bucketName,String objectName) throws IOException {InputStream inputStream = null;OutputStream outputStream = null;try {GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket(bucketName).object(objectName).build();inputStream = minioClient.getObject(getObjectArgs);File file = new File("D:/Download/" + objectName);outputStream = new FileOutputStream(file);IOUtils.copy(inputStream,outputStream);}catch (Exception e){e.printStackTrace();log.info("下载失败");return false;}finally {try {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}} catch (Exception e) {e.printStackTrace();}}return true;}/*** 下载文件* @param bucketName 桶名* @param objectName 对象名* @param fileName 下载到本地路径* @return* @throws Exception*/public boolean downloadObject(String bucketName, String objectName, String fileName) throws Exception {try {DownloadObjectArgs downloadObjectArgs = DownloadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build();minioClient.downloadObject(downloadObjectArgs);log.info("下载成功");return true;}catch (Exception e) {e.printStackTrace();log.info("下载失败");return false;}}/*** 获取所有桶* @return 桶集合*/public List<Bucket> getAllBuckets(){List<Bucket> buckets = null;try {buckets = minioClient.listBuckets();}catch (Exception e){e.printStackTrace();log.info("获取桶失败");return null;}return buckets;}/*** 获取所有桶名* @return 桶名集合*/public List<String> getAllBucketNames(){List<Bucket> allBuckets = getAllBuckets();List<String> collect = null;if (CollUtil.isNotEmpty(allBuckets)){collect = allBuckets.stream().map(Bucket::name).collect(Collectors.toList());}return collect;}/*** 获取桶内所有对象* @param bucketName 桶名* @return 返回对象集合*/public Iterable<Result<Item>> listObjects(String bucketName){try {ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder().bucket(bucketName).build();return minioClient.listObjects(listObjectsArgs);}catch (Exception e){e.printStackTrace();log.info("获取桶失败");return null;}}}

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

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

相关文章

第一个C++程序|cin和cout|命名空间

第一个C程序 基础程序 使用DevC5.4.0 写一个C程序 在屏幕上打印hello world #include <iostream> using namespace std;int main() {cout << "hello world" << endl;return 0; } 运行这个C程序 F9->编译 F10->运行 F11->编译运行 mai…

【大模型】wiki中文语料的word2vec模型构建

在自然语言处理&#xff08;NLP&#xff09;任务中&#xff0c;词向量&#xff08;Word Embedding&#xff09;是一个非常重要的概念。通过将词语映射到一个高维空间中&#xff0c;我们能够以向量的形式表达出词语之间的语义关系。Word2Vec作为一种流行的词向量学习方法&#x…

1.RPC基本原理

文章目录 RPC1.定义2.概念3.优缺点4.RPC结构5.RPC消息协议5.1 消息边界5.2 内容5.3 压缩 6.RPC的实现6.1 divide_protocol.py6.2 server.py6.3 client.py RPC 1.定义 远程过程调用(remote procedure call) 2.概念 广义:所有通过网络进行通讯,的调用统称为RPC调用 狭义:不采…

强化特种作业管理,筑牢安全生产防线

在各类生产经营活动中&#xff0c;特种作业由于其操作的特殊性和高风险性&#xff0c;一直是安全生产管理的重点领域。有效的特种作业管理体系涵盖多个关键方面&#xff0c;从作业人员的资质把控到安全设施的配备维护&#xff0c;再到特种设备的精细管理以及作业流程的严格规范…

iOS 苹果开发者账号: 查看和添加设备UUID 及设备数量

参考链接&#xff1a;苹果开发者账号下添加新设备UUID - 简书 如果要添加新设备到 Profiles 证书里&#xff1a; 1.登录开发者中心 Sign In - Apple 2.找到证书设置&#xff1a; Certificate&#xff0c;Identifiers&Profiles > Profiles > 选择对应证书 edit &g…

基于单片机的大型家禽养殖基地智能环境控制系统构建

摘要:我国是一个大型家禽养殖大国,无论是大型家禽养殖数量或是大型家禽相关产品总量都位居世界前列。但是我国的大型家禽相关产品的市场竞争力却表现的差强人意,与一些发达国家的同类产品相比还有较大的差距。导致这一情况主要是因为我国很多大型家禽养殖基地往往只关注大型…

如何让Tplink路由器自身的IP网段 与交换机和电脑的IP网段 保持一致?

问题分析&#xff1a; 正常情况下&#xff0c;我的需求是&#xff1a;电脑又能上网&#xff0c;又需要与路由器处于同一局域网下&#xff08;串流Pico4 VR眼镜&#xff09;&#xff0c;所以&#xff0c;我是这么连接 交换机、路由器、电脑 的&#xff1a; 此时&#xff0c;登录…

视听语言与手机拍摄技巧

视听语言----------------------------------------- 景别&#xff1a;远全中近特 远景&#xff1a;人物只占画面很小的一部分&#xff0c;主要展示环境&#xff08;背景为画面主体&#xff0c;人物占画面很小的一部分&#xff09;–》定调子&#xff08;确定电影基调&#xf…

企业安全建设——安全防线框架建设(一)

前言 为什么会有此篇文章&#xff0c;早期的攻击&#xff0c;从弱口令&#xff0c;SQL注入&#xff0c;上传漏洞&#xff0c;演变到现在的反序列化&#xff0c;供应链&#xff0c;公私云&#xff0c;区块链等攻击方式&#xff0c;早期的防御方式从防火墙&#xff0c;防病毒&am…

(南京观海微电子)——GH7009开机黑屏案例分析

一、 现象描述&#xff1a; 不良现象: LVDS模组&#xff0c;开机大概2秒后就黑屏。 二、问题分析 等主机进入Kernel 后做以下测试&#xff1a; 1、手动reset LCM 后 可以显示正常&#xff1b; 总结&#xff1a; 1&#xff09;uboot 部分HS 太窄&#xff0c;仅有4个clk宽度&am…

第10章 初等数论

2024年12月27日一稿&#xff08;P341&#xff09; 2024年12月28日二稿 2024年12月29日三稿 当命运这扇大门向你打开的时候&#xff0c;不要犹豫和害怕&#xff0c;一直往前跑就是了&#xff01; 10.1 素数 这里写错了&#xff0c;不能整除应该表示为 10.2 最大公约数与最小公…

XXE漏洞 黑盒测试 白盒测试 有无回显问题

前言 什么是XXE&#xff08;xml外部实体注入漏洞&#xff09;&#xff1f; 就是网站以xml传输数据 的时候我们截取他的传输流进行修改&#xff08;网站没有对我们的输入进行过滤&#xff09; 添加恶意代码 导致数据传输到后台 后台解析xml形式 导致恶意代码被执行 几种常见的…

yolov5 yolov6 yolov7 yolov8 yolov9目标检测、目标分类 目标切割 性能对比

文章目录 YOLOv1-YOLOv8之间的对比如下表所示&#xff1a;一、YOLO算法的核心思想1. YOLO系列算法的步骤2. Backbone、Neck和Head 二、YOLO系列的算法1.1 模型介绍1.2 网络结构1.3 实现细节1.4 性能表现 2. YOLOv2&#xff08;2016&#xff09;2.1 改进部分2.2 网络结构 3. YOL…

NV-Embed详细技术解析

NV-Embed详细技术解析 1. 方法论 1.1 双向注意力 背景&#xff1a;解码器块中的因果掩码原本用于防止自回归文本生成时的信息泄露创新&#xff1a;在对比学习过程中移除因果注意力掩码优势&#xff1a;提升模型的表示能力,允许双向信息流动 1.2 潜在注意力层 动机&#xf…

jdk版本介绍

1.JDK版本编号 • 主版本号&#xff1a;表示JDK的主要版本&#xff0c;如JDK 8、JDK 11中的8和11。主版本号的提升通常意味着引入了重大的新特性或变更。 • 次版本号&#xff1a;在主版本号之后&#xff0c;有时会跟随一个或多个次版本号&#xff08;如JDK 11.0.2中的0.2&…

低代码开源项目Joget的研究——基本概念和Joget7社区版应用

大纲 1. 基本概念1.1 Form1.1.1 Form1.1.1.1 概述1.1.1.2 主要特点和用途1.1.1.3 创建和使用 Form1.1.1.4 示例 1.1.2 Section1.1.2.1 概述1.1.2.2 主要特点和用途1.1.2.3 示例 1.1.3 Column1.1.4 Field1.1.5 示例 1.2 Datalist1.2.1 Datalist1.2.1.1 主要特点和用途1.2.1.2 创…

【LeetCode 04】 209. 长度最小的子数组

暴力解法&#xff1a; 测试通过✅提交超时❌ class Solution {public int minSubArrayLen(int target, int[] nums) {//暴力解法int sum0;int subLength0;int resultInteger.MAX_VALUE;int lennums.length;for(int i0;i<len;i){//起始位置sum0;for(int ji;j<len;j){//终…

【已解决】图片png转ico格式

起因&#xff1a; pyinstaller 打包时需要 ico 格式图片&#xff0c;但是通常手上只有png格式的图片&#xff0c;为了将png转为ico&#xff0c;直接改后缀会报错“struct.error: unpack requires a buffer of 16 bytes”&#xff0c;我就上网搜了一下&#xff0c;发现都是一些…

Java 中 Stream 流的使用详解

Java 中 Stream 流的使用详解 什么是 Stream&#xff1f; Stream 是 Java 8 引入的一种全新的操作集合的方式。它支持通过声明性方式对集合进行复杂的数据操作&#xff08;如过滤、排序、聚合等&#xff09;&#xff0c;避免使用大量的 for 循环&#xff0c;提高代码的可读性…

AMD | GPU | 深度学习 | 如何使用

问题&#xff1a;我在复现代码的时候&#xff0c;发现自己只拥有AMD的GPU&#xff0c;对于一个硬件小白来说&#xff0c;怎么办呢&#xff1f;我想看看怎么使用&#xff1b;解决&#xff1a; 首先要安装支持AMD的GPU的pytorch&#xff0c;pytorch&#xff1b; 使程序在安装了支…