【Java编程系列】Minio实现文件上传下载 妖狐艹你老母 2024-04-08 09:53 19阅读 0赞 ## 热门系列: ## #### [【Java编程系列】Amazon S3实现文件上传下载][Java_Amazon S3] #### -------------------- ## **目录** ## **热门系列:** **1、前言** **2、Minio实战代码** **2.1 Minio环境部署** **2.2 Minio的Sdk对接实现** **2.2.1 Minio Maven依赖** **2.2.2 minio配置与初始化** **2.2.3 上传文件** **2.2.4 下载文件** **2.2.5 生成文件预签名url** **2.2.6 文件永久性访问实现** **2.2.7 删除文件** **2.2.8 其他操作** **3、总结** -------------------- ## 1、前言 ## 最近给一个租户做**minio**的独立存储部署,使用过程中,有了一点使用心得,做一个记录分享,希望可以帮到有需要的朋友~~~ -------------------- ## 2、Minio实战代码 ## ### 2.1 Minio环境部署 ### 进入下载链接:[https://dl.min.io/server/minio/release/][https_dl.min.io_server_minio_release] ,按需下载对应版本后,安装完毕即可。装载完成,启动minio后,可以直接打开对应的可视化界面,输入[http://ip:9000/][http_ip_9000],如下图,表示部署安装成功啦(安装细节在本文展开,不清楚的童靴请搜索一下): ![16e32859b5dd4616af9856b943e59bff.png][] ### 2.2 Minio的Sdk对接实现 ### #### 2.2.1 Minio Maven依赖 #### 引入相关java sdk所需依赖: <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.2.2</version> </dependency> #### 2.2.2 minio配置与初始化 #### 先设置minio的一些配置信息: minio: url: http://127.0.0.1:9000 #安装minio的服务器ip bucket: news #创建的存储桶名称(可界面创建,亦可sdk代码创建) accessKey: testkey #minio登录账号 secretKey: testpassword #minio登录密码 通过配置类读取配置信息,为后续使用做准备: package ***.***.***.***.configure; import lombok.Data; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "minio") public class MinioProperties { private String accessKey; private String secretKey; private String url; private String bucket; } 初始化minio客户端: package ***.***.***.utils; import ***.***.***.MinioProperties; import io.minio.BucketExistsArgs; import io.minio.GetObjectArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MinioClientUtil { @Autowired private MinioProperties properties; private MinioClient client; //初始化minio client private void init() throws NoSuchAlgorithmException, InvalidKeyException, IOException, InvalidResponseException, InsufficientDataException, ServerException, ErrorResponseException, XmlParserException, InternalException { if (null != client) { return; } client = MinioClient.builder() .endpoint(properties.getUrl()) .credentials(properties.getAccessKey(), properties.getSecretKey()) .build(); makeBucket(properties.getBucket()); } //创建自定义的存储桶 //这里只做了简单的桶存在判断,这里还可以添加设置桶的策略等 public void makeBucket(String bucket) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { boolean bucketExist = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); if (!bucketExist) { client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build()); } } } #### 2.2.3 上传文件 #### import io.minio.BucketExistsArgs; import io.minio.GetObjectArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MinioClientUtil { /** * @return void * @Description * @Date 11:58 2022/8/19 * @Param [bucket=同名称, fileName=文件路径即名称, ins=上传的输入流, fileSize=上传的文件大小] **/ public void uploadFile(String bucket, String fileName, InputStream ins, long fileSize) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { init(); makeBucket(bucket); PutObjectArgs.Builder putObjectArgsBuilder = PutObjectArgs.builder() .bucket(bucket) .object(fileName) .stream(ins, fileSize, 5 * 1024 * 1024); client.putObject(putObjectArgsBuilder.build()); } } #### 2.2.4 下载文件 #### import io.minio.BucketExistsArgs; import io.minio.GetObjectArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.RemoveObjectArgs; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MinioClientUtil { /** * @return java.io.InputStream * @Description * @Date 12:09 2022/8/19 * @Param [bucket=存储桶名称, fileName=文件路径即名称] **/ public InputStream download(String bucket, String fileName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { init(); GetObjectArgs.Builder getObjectArgsBuilder = GetObjectArgs.builder() .bucket(bucket) .object(fileName); return client.getObject(getObjectArgsBuilder.build()); } } #### 2.2.5 生成文件预签名url #### import io.minio.BucketExistsArgs; import io.minio.GetObjectArgs; import io.minio.GetPresignedObjectUrlArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import io.minio.http.Method; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MinioClientUtil { /** * @return java.lang.String * @Description * @Date 12:14 2022/8/19 * @Param [bucket=存储桶名称, fileName=文件路径即名称] **/ private String getMinioURL(String bucket, String fileName) throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, ServerException, XmlParserException, InternalException, InsufficientDataException, ErrorResponseException { if (null == client) { init(); } GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(bucket) .object(fileName) .expiry(60 * 60 * 24) //生成的预签名url可访问的有效时间,最大期限7天 .build(); return client.getPresignedObjectUrl(build); } } #### #### #### 2.2.6 文件永久性访问实现 #### 这里做永久访问有效实现,是为了应对一种场景。例如,**我们的图片文件,需要直接通过url(非下载后)可显示或打开,在系统用户头像这里,就可能会要求如此实现**。因此,我们需要保证我们生成的图片url只可以直接访问的。 但是,通过上述**预签名url的生成方式,有一个最大时效7天的限制**,所以此方式暂不考虑。 minio其实也提供了,文件直接通过ip端口或域名的方式访问的,即用url访问minio存储桶中的文件。要想能直接通过自己定义的**ip+端口+图片路径**来访问的话,需要将minio指定存储桶的访问策略调整一下,如下图所示: ![e6d55206a32d4ea09b014fc134233335.png][] ![08c6ff467de54497b425f03a40616381.png][] 点击add,策略选Read Only就行了,就可以访问了。 ![56ec2290d51643d79a30e256a7d80bd2.png][] 然后,通过**http://ip:9000/同名/文件路径及名称**的URL形式,就可以永久访问到这个图片文件啦~~ 这里有一个访问形式上的微调,可能有的系统,是使用域名访问的,这个时候域名的一些端口都是通过nginx指定统一了,那这个时候,对于minio如果需要使用域名访问,则需要把nginx再指定配置一下,就可以啦! #### 2.2.7 删除文件 #### import io.minio.BucketExistsArgs; import io.minio.GetObjectArgs; import io.minio.GetPresignedObjectUrlArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import io.minio.errors.ErrorResponseException; import io.minio.errors.InsufficientDataException; import io.minio.errors.InternalException; import io.minio.errors.InvalidResponseException; import io.minio.errors.ServerException; import io.minio.errors.XmlParserException; import io.minio.http.Method; import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; public class MinioClientUtil { /** * @return void * @Description * @Date 14:19 2022/8/19 * @Param [bucket=存储桶名称, fileName=文件路径即名称] **/ public void delete(String bucket, String fileName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { init(); client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(fileName).build()); } } #### 2.2.8 其他操作 #### 以上就为minio的主要操作sdk的实现了。另外有一个操作,这边就不一 一列举了。例如 获取桶对象、桶列表、存储文件列表等等,可以自行按需实践一番~~~ -------------------- ## 3、总结 ## 在使用minio的过程中,发现了几处需要注意的点: 1、minio在同一路径下的文件,如果名称相同,则会被覆盖掉。所以,建议可以考虑加文件前加:**yyyy-MM-dd/时间戳-文件名**的方式来实现区分存储 2、minio对于存储文件的单个文件的大小,暂无明确大小上限,一个对象文件可以是任意大小,从几 kb 到最大 5T 不等 最后,对于minio的加密处理方式,暂时还没有研究完,可能后续补充完善。 对博文内容有疑问的地方,欢迎下方留言讨论,看到必回复大家~~~~ [Java_Amazon S3]: https://yangy.blog.csdn.net/article/details/126411649 [https_dl.min.io_server_minio_release]: https://dl.min.io/server/minio/release/ [http_ip_9000]: http://172.16.50.100:9000/ [16e32859b5dd4616af9856b943e59bff.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/08/0ca77e8db11e4d9a9283a81ed9c13807.png [e6d55206a32d4ea09b014fc134233335.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/08/c9f5139f4c43422e8034dbe3a41ee00c.png [08c6ff467de54497b425f03a40616381.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/08/ff766d370d83405fa83a4aa55b26f4a3.png [56ec2290d51643d79a30e256a7d80bd2.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/08/39c336df82df4ec39fe0405bce88b913.png
还没有评论,来说两句吧...