当前位置:   article > 正文

minio的基本使用——java_minio java

minio java

第一步:下载minio服务安装包

去官网下载:MinIO | 用于创建高性能对象存储的代码和下载内容

minio的使用文档:MinIO Object Storage for Kubernetes — MinIO Object Storage for Kubernetes

MinIo有两个重要的对象,服务器minio.exe和客户端minio.client。搭建服务器用于接收文件信息,客户端用于上传文件。

官网下载有些慢

记住一点:如果是下载windows版本的,切记千万不能去双击运行,这样可能会导致最终启动失败;无论是windows还是linux都是通过命令启动的。

第二步:启动minio服务器

1.minio服务的启动命令

在windows环境下,在你的minio.exe文件所在位置的文件夹下(最好在同级路径下创建一个类似data的文件夹,用于存储数据),打开cmd命令框,

输入:minio.exe server D:\Java_study\javaEE-study\JAVA\minio\data (后面的数据存储路径文件夹是自定义的)

(如果是linux启动minio服务器,则在对应的minio存放的路径下输入:./minio server ./data)

2.访问minio服务器

打开浏览器输入上面的访问地址和端口即可访问minio服务器的ui界面

 3.minio服务端主界面简单介绍

点开任意一个桶

​ 4.纯java入门minio参考

  1. package com.jdh.minio;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.InputStream;
  5. import java.util.List;
  6. import io.minio.*;
  7. import io.minio.messages.Bucket;
  8. /**
  9. * @ClassName: FileUploader
  10. * @Author: jdh
  11. * @CreateTime: 2022-04-15
  12. * @Description: minio基本操作demo
  13. */
  14. public class FileUploader {
  15. public static void main(String[] args) {
  16. try {
  17. // 创建客户端
  18. MinioClient minioClient =
  19. MinioClient.builder()
  20. // api地址
  21. .endpoint("127.0.0.1",9000,true)
  22. // .endpoint("http://127.0.0.1:9000")
  23. // 前面设置的账号密码
  24. .credentials("minioadmin", "minioadmin")
  25. .build();
  26. System.out.println(minioClient);
  27. // 检查桶是否存在
  28. boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("test").build());
  29. if (!found) {
  30. // 创建桶
  31. minioClient.makeBucket(MakeBucketArgs.builder().bucket("test").build());
  32. }
  33. //列出所有桶名
  34. List<Bucket> buckets = minioClient.listBuckets();
  35. for (Bucket i : buckets){
  36. System.out.println(i.name());
  37. }
  38. //删除某一个桶
  39. // minioClient.removeBucket(
  40. // RemoveBucketArgs.builder()
  41. // .bucket("桶名称")
  42. // .build());
  43. System.out.println("开始你的操作");
  44. File file = new File("D:\\Java_study\\javaEE-study\\user.xlsx");
  45. String fileName = file.getName();
  46. String realFileName = fileName.substring(fileName.lastIndexOf("\\")+1, fileName.lastIndexOf("."));
  47. String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
  48. //通过路径上传一个文件
  49. ObjectWriteResponse testDir = minioClient.uploadObject(
  50. UploadObjectArgs.builder()
  51. .bucket("test")
  52. .object("user_Path1")//文件名字
  53. .filename("D:\\Java_study\\javaEE-study\\user.xlsx")//文件存储的路径
  54. .contentType(fileType)
  55. .build());
  56. //通过文件格式上传一个文件
  57. InputStream fileInputStream = new FileInputStream(file);
  58. long size = file.length();
  59. minioClient.putObject(
  60. PutObjectArgs.builder()
  61. .bucket("test")
  62. .object("user_File1")
  63. .stream(fileInputStream, size, -1)
  64. .contentType(fileType)
  65. .build());
  66. //文件下载,都是这种下载到指定路径
  67. minioClient.downloadObject(DownloadObjectArgs.builder()
  68. .bucket("test")
  69. .object("user")
  70. .filename("D:\\Java_study\\javaEE-study\\user_test.xlsx")
  71. .build());
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. }

 第三步:java整合minio

此demo演示的是springboot项目整合minio,demo中minio版本是8.0.3,但参考版本最低7.x以上。

demo项目gitee连接:https://gitee.com/java_utils_demo/java_minio_demo.git

1.创建一个springboot的项目

2.在pom里面引入对应的依赖

(新手别忘记引入springboot的父依赖)

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-test</artifactId>
  13. </dependency>
  14. <!--此依赖为minio的服务依赖-->
  15. <dependency>
  16. <groupId>io.minio</groupId>
  17. <artifactId>minio</artifactId>
  18. <version>8.0.3</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>com.alibaba.fastjson2</groupId>
  22. <artifactId>fastjson2</artifactId>
  23. <version>2.0.12</version>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.projectlombok</groupId>
  27. <artifactId>lombok</artifactId>
  28. </dependency>
  29. </dependencies>

 3.在application.yml配置文件配置

下面的配置实际可有可无,只是在创建minio的客户端的时候需要的一些连接服务端的一些相关配置信息

  1. server:
  2. port: 8080
  3. # Minio配置
  4. minio:
  5. config:
  6. ip: 127.0.0.1 #ip地址
  7. port: 9000 # 端口号
  8. accessKey: minioadmin # 账号
  9. secretKey: minioadmin # 密码
  10. secure: false #如果是true,则用的是https而不是http,默认值是true
  11. bucketName: "jdh-bucket" # 桶的名字
  12. downloadDir: "/data/excel" #保存到本地的路径

 4.创建一个配置文件类

下面配置文件类就是通过spring的ConfigurationProperties注解完成配置文件中相关参数的注入

  1. package com.jdh.minio.config;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * @ClassName: MinioProperties
  7. * @Author: jdh
  8. * @CreateTime: 2022-04-15
  9. * @Description:
  10. */
  11. @Component
  12. @Data
  13. @ConfigurationProperties(prefix = "minio.config")
  14. public class MinioProperties {
  15. /**
  16. * API调用地址ip
  17. */
  18. private String ip;
  19. /**
  20. * API调用地址端口
  21. */
  22. private Integer port;
  23. /**
  24. * 连接账号
  25. */
  26. private String accessKey;
  27. /**
  28. * 连接秘钥
  29. */
  30. private String secretKey;
  31. /**
  32. * minio存储桶的名称
  33. */
  34. private String bucketName;
  35. /**
  36. * 文件下载到本地的路径
  37. */
  38. private String downloadDir;
  39. /**
  40. * #如果是true,则用的是https而不是http,默认值是true
  41. */
  42. private Boolean secure;
  43. }

5.封装一些简单的方法

如:获取一个minio连接客户端、文件上下传封装、创建\删除桶、列出所有桶\文件信息等

  1. package com.jdh.minio.config;
  2. import io.minio.*;
  3. import io.minio.errors.*;
  4. import io.minio.http.Method;
  5. import io.minio.messages.Bucket;
  6. import io.minio.messages.DeleteObject;
  7. import io.minio.messages.Item;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.util.StringUtils;
  12. import org.springframework.web.multipart.MultipartFile;
  13. import javax.annotation.Resource;
  14. import javax.servlet.http.HttpServletResponse;
  15. import java.io.*;
  16. import java.security.InvalidKeyException;
  17. import java.security.NoSuchAlgorithmException;
  18. import java.time.LocalDateTime;
  19. import java.time.ZonedDateTime;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.UUID;
  23. import java.util.concurrent.TimeUnit;
  24. /**
  25. * @ClassName: MinioFile
  26. * @Author: jdh
  27. * @CreateTime: 2022-04-15
  28. * @Description:
  29. */
  30. @Configuration
  31. @Slf4j
  32. public class MinioFileUtil {
  33. @Resource
  34. private MinioProperties minioProperties;
  35. private MinioClient minioClient;
  36. /**
  37. * 这个是6.0.左右的版本
  38. * @return MinioClient
  39. */
  40. // @Bean
  41. // public MinioClient getMinioClient(){
  42. //
  43. // String url = "http:" + minioProperties.getIp() + ":" + minioProperties.getPort();
  44. //
  45. // try {
  46. // return new MinioClient(url, minioProperties.getAccessKey(), minioProperties.getSecretKey());
  47. // } catch (InvalidEndpointException | InvalidPortException e) {
  48. // e.printStackTrace();
  49. // log.info("-----创建Minio客户端失败-----");
  50. // return null;
  51. // }
  52. // }
  53. /**
  54. * 下面这个和上面的意思差不多,但是这个是新版本
  55. * 获取一个连接minio服务端的客户端
  56. *
  57. * @return MinioClient
  58. */
  59. @Bean
  60. public MinioClient getClient() {
  61. String url = "http:" + minioProperties.getIp() + ":" + minioProperties.getPort();
  62. MinioClient minioClient = MinioClient.builder()
  63. .endpoint(url) //两种都可以,这种全路径的其实就是下面分开配置一样的
  64. // .endpoint(minioProperties.getIp(),minioProperties.getPort(),minioProperties.getSecure())
  65. .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
  66. .build();
  67. this.minioClient = minioClient;
  68. return minioClient;
  69. }
  70. /**
  71. * 创建桶
  72. *
  73. * @param bucketName 桶名称
  74. */
  75. public void createBucket(String bucketName) throws Exception {
  76. if (!StringUtils.hasLength(bucketName)) {
  77. throw new RuntimeException("创建桶的时候,桶名不能为空!");
  78. }
  79. // Create bucket with default region.
  80. minioClient.makeBucket(MakeBucketArgs.builder()
  81. .bucket(bucketName)
  82. .build());
  83. }
  84. /**
  85. * 创建桶,固定minio容器
  86. *
  87. * @param bucketName 桶名称
  88. */
  89. public void createBucketByRegion(String bucketName, String region) throws Exception {
  90. if (!StringUtils.hasLength(bucketName)) {
  91. throw new RuntimeException("创建桶的时候,桶名不能为空!");
  92. }
  93. MinioClient minioClient = this.getClient();
  94. // Create bucket with specific region.
  95. minioClient.makeBucket(MakeBucketArgs.builder()
  96. .bucket(bucketName)
  97. .region(region) //
  98. .build());
  99. // // Create object-lock enabled bucket with specific region.
  100. // minioClient.makeBucket(
  101. // MakeBucketArgs.builder()
  102. // .bucket("my-bucketname")
  103. // .region("us-west-1")
  104. // .objectLock(true)
  105. // .build());
  106. }
  107. /**
  108. * 修改桶名
  109. * (minio不支持直接修改桶名,但是可以通过复制到一个新的桶里面,然后删除老的桶)
  110. *
  111. * @param oldBucketName 桶名称
  112. * @param newBucketName 桶名称
  113. */
  114. public void renameBucket(String oldBucketName, String newBucketName) throws Exception {
  115. if (!StringUtils.hasLength(oldBucketName) || !StringUtils.hasLength(newBucketName)) {
  116. throw new RuntimeException("修改桶名的时候,桶名不能为空!");
  117. }
  118. }
  119. /**
  120. * 删除桶
  121. *
  122. * @param bucketName 桶名称
  123. */
  124. public void deleteBucket(String bucketName) throws Exception {
  125. if (!StringUtils.hasLength(bucketName)) {
  126. throw new RuntimeException("删除桶的时候,桶名不能为空!");
  127. }
  128. minioClient.removeBucket(
  129. RemoveBucketArgs.builder()
  130. .bucket(bucketName)
  131. .build());
  132. }
  133. /**
  134. * 检查桶是否存在
  135. *
  136. * @param bucketName 桶名称
  137. * @return boolean true-存在 false-不存在
  138. */
  139. public boolean checkBucketExist(String bucketName) throws Exception {
  140. if (!StringUtils.hasLength(bucketName)) {
  141. throw new RuntimeException("检测桶的时候,桶名不能为空!");
  142. }
  143. return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
  144. }
  145. /**
  146. * 列出所有的桶
  147. *
  148. * @return 所有桶名的集合
  149. */
  150. public List<Bucket> getAllBucketInfo() throws Exception {
  151. //列出所有桶
  152. List<Bucket> buckets = minioClient.listBuckets();
  153. return buckets;
  154. }
  155. /**
  156. * 列出某个桶中的所有文件名
  157. * 文件夹名为空时,则直接查询桶下面的数据,否则就查询当前桶下对于文件夹里面的数据
  158. *
  159. * @param bucketName 桶名称
  160. * @param folderName 文件夹名
  161. * @param isDeep 是否递归查询
  162. */
  163. public Iterable<Result<Item>> getBucketAllFile(String bucketName, String folderName, Boolean isDeep) throws Exception {
  164. if (!StringUtils.hasLength(bucketName)) {
  165. throw new RuntimeException("获取桶中文件列表的时候,桶名不能为空!");
  166. }
  167. if (!StringUtils.hasLength(folderName)) {
  168. folderName = "";
  169. }
  170. System.out.println(folderName);
  171. Iterable<Result<Item>> listObjects = minioClient.listObjects(
  172. ListObjectsArgs
  173. .builder()
  174. .bucket(bucketName)
  175. .prefix(folderName + "/")
  176. .recursive(isDeep)
  177. .build());
  178. // for (Result<Item> result : listObjects) {
  179. // Item item = result.get();
  180. // System.out.println(item.objectName());
  181. // }
  182. return listObjects;
  183. }
  184. /**
  185. * 删除文件夹
  186. *
  187. * @param bucketName 桶名
  188. * @param objectName 文件夹名
  189. * @param isDeep 是否递归删除
  190. * @return
  191. */
  192. public Boolean deleteBucketFile(String bucketName, String objectName) {
  193. if (!StringUtils.hasLength(bucketName) || !StringUtils.hasLength(objectName)) {
  194. throw new RuntimeException("删除文件的时候,桶名或文件名不能为空!");
  195. }
  196. try {
  197. minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
  198. return true;
  199. } catch (Exception e) {
  200. log.info("删除文件失败");
  201. return false;
  202. }
  203. }
  204. /**
  205. * 删除文件夹
  206. *
  207. * @param bucketName 桶名
  208. * @param objectName 文件夹名
  209. * @param isDeep 是否递归删除
  210. * @return
  211. */
  212. public Boolean deleteBucketFolder(String bucketName, String objectName, Boolean isDeep) {
  213. if (!StringUtils.hasLength(bucketName) || !StringUtils.hasLength(objectName)) {
  214. throw new RuntimeException("删除文件夹的时候,桶名或文件名不能为空!");
  215. }
  216. try {
  217. ListObjectsArgs args = ListObjectsArgs.builder().bucket(bucketName).prefix(objectName + "/").recursive(isDeep).build();
  218. Iterable<Result<Item>> listObjects = minioClient.listObjects(args);
  219. listObjects.forEach(objectResult -> {
  220. try {
  221. Item item = objectResult.get();
  222. minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(item.objectName()).build());
  223. } catch (Exception e) {
  224. log.info("删除文件夹中的文件异常", e);
  225. }
  226. });
  227. return true;
  228. } catch (Exception e) {
  229. log.info("删除文件夹失败");
  230. return false;
  231. }
  232. }
  233. /**
  234. * 获取文件下载地址
  235. *
  236. * @param bucketName 桶名
  237. * @param objectName 文件名
  238. * @param expires 过期时间,默认秒
  239. * @return
  240. * @throws Exception
  241. */
  242. public String getFileDownloadUrl(String bucketName, String objectName, Integer expires) throws Exception {
  243. GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
  244. .method(Method.GET)//下载地址的请求方式
  245. .bucket(bucketName)
  246. .object(objectName)
  247. .expiry(expires, TimeUnit.SECONDS)//下载地址过期时间
  248. .build();
  249. String objectUrl = minioClient.getPresignedObjectUrl(args);
  250. return objectUrl;
  251. }
  252. /**
  253. * 获取文件上传地址(暂时还未实现)
  254. *
  255. * @param bucketName 桶名
  256. * @param objectName 文件名
  257. * @param expires 过期时间,默认秒
  258. * @return
  259. * @throws Exception
  260. */
  261. public String getFileUploadUrl(String bucketName, String objectName, Integer expires) throws Exception {
  262. // 过期时间
  263. ZonedDateTime zonedDateTime = ZonedDateTime.now().plusSeconds(60);
  264. PostPolicy postPolicy = new PostPolicy(bucketName, zonedDateTime);
  265. // 获取对象的默认权限策略
  266. StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
  267. String objectPolicy = statObjectResponse.headers().get("x-amz-object-policy");
  268. String presignedObjectUrl = minioClient.getPresignedObjectUrl(
  269. GetPresignedObjectUrlArgs.builder()
  270. .bucket(bucketName)
  271. .object(objectName)
  272. .method(Method.POST)
  273. .expiry(expires) // 预签名的 URL 有效期为 1 小时
  274. .build());
  275. MyMinioClient client = new MyMinioClient(minioClient);
  276. return presignedObjectUrl;
  277. }
  278. /**
  279. * 创建文件夹
  280. *
  281. * @param bucketName 桶名
  282. * @param folderName 文件夹名称
  283. * @return
  284. * @throws Exception
  285. */
  286. public ObjectWriteResponse createBucketFolder(String bucketName, String folderName) throws Exception {
  287. if (!checkBucketExist(bucketName)) {
  288. throw new RuntimeException("必须在桶存在的情况下才能创建文件夹");
  289. }
  290. if (!StringUtils.hasLength(folderName)) {
  291. throw new RuntimeException("创建的文件夹名不能为空");
  292. }
  293. PutObjectArgs putObjectArgs = PutObjectArgs.builder()
  294. .bucket(bucketName)
  295. .object(folderName + "/")
  296. .stream(new ByteArrayInputStream(new byte[0]), 0, 0)
  297. .build();
  298. ObjectWriteResponse objectWriteResponse = minioClient.putObject(putObjectArgs);
  299. return objectWriteResponse;
  300. }
  301. /**
  302. * 检测某个桶内是否存在某个文件
  303. *
  304. * @param objectName 文件名称
  305. * @param bucketName 桶名称
  306. */
  307. public boolean getBucketFileExist(String objectName, String bucketName) throws Exception {
  308. if (!StringUtils.hasLength(objectName) || !StringUtils.hasLength(bucketName)) {
  309. throw new RuntimeException("检测文件的时候,文件名和桶名不能为空!");
  310. }
  311. try {
  312. // 判断文件是否存在
  313. boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()) &&
  314. minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()) != null;
  315. return exists;
  316. } catch (ErrorResponseException e) {
  317. log.info("文件不存在 ! Object does not exist");
  318. return false;
  319. } catch (Exception e) {
  320. throw new Exception(e);
  321. }
  322. }
  323. /**
  324. * 判断桶中是否存在文件夹
  325. *
  326. * @param bucketName 同名称
  327. * @param objectName 文件夹名称
  328. * @param isDeep 是否递归查询(暂不支持)
  329. * @return
  330. */
  331. public Boolean checkBucketFolderExist(String bucketName, String objectName, Boolean isDeep) {
  332. Iterable<Result<Item>> results = minioClient.listObjects(
  333. ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(isDeep).build());
  334. return results.iterator().hasNext(); // 文件夹下存在文件
  335. }
  336. /**
  337. * 根据MultipartFile file上传文件
  338. * minio 采用文件流上传,可以换成下面的文件上传
  339. *
  340. * @param file 上传的文件
  341. * @param bucketName 上传至服务器的桶名称
  342. */
  343. public boolean uploadFile(MultipartFile file, String bucketName) throws Exception {
  344. if (file == null || file.getSize() == 0 || file.isEmpty()) {
  345. throw new RuntimeException("上传文件为空,请重新上传");
  346. }
  347. if (!StringUtils.hasLength(bucketName)) {
  348. log.info("传入桶名为空,将设置默认桶名:" + minioProperties.getBucketName());
  349. bucketName = minioProperties.getBucketName();
  350. if (!this.checkBucketExist(minioProperties.getBucketName())) {
  351. this.createBucket(minioProperties.getBucketName());
  352. }
  353. }
  354. if (!this.checkBucketExist(bucketName)) {
  355. throw new RuntimeException("当前操作的桶不存在!");
  356. }
  357. // 获取上传的文件名
  358. String filename = file.getOriginalFilename();
  359. assert filename != null;
  360. //可以选择生成一个minio中存储的文件名称
  361. String minioFilename = UUID.randomUUID().toString() + "_" + filename;
  362. String url = "http:" + minioProperties.getIp() + ":" + minioProperties.getPort();
  363. InputStream inputStream = file.getInputStream();
  364. long size = file.getSize();
  365. String contentType = file.getContentType();
  366. // Upload known sized input stream.
  367. minioClient.putObject(
  368. PutObjectArgs.builder()
  369. .bucket(bucketName) //上传到指定桶里面
  370. .object(minioFilename)//文件在minio中存储的名字
  371. //p1:上传的文件流;p2:上传文件总大小;p3:上传的分片大小
  372. .stream(inputStream, size, -1) //上传分片文件流大小,如果分文件上传可以采用这种形式
  373. .contentType(contentType) //文件的类型
  374. .build());
  375. return this.getBucketFileExist(minioFilename, bucketName);
  376. }
  377. /**
  378. * 上传本地文件,根据路径上传
  379. * minio 采用文件内容上传,可以换成上面的流上传
  380. *
  381. * @param filePath 上传本地文件路径
  382. * @Param bucketName 上传至服务器的桶名称
  383. */
  384. public boolean uploadPath(String filePath, String bucketName) throws Exception {
  385. File file = new File(filePath);
  386. if (!file.isFile()) {
  387. throw new RuntimeException("上传文件为空,请重新上传");
  388. }
  389. if (!StringUtils.hasLength(bucketName)) {
  390. log.info("传入桶名为空,将设置默认桶名:" + minioProperties.getBucketName());
  391. bucketName = minioProperties.getBucketName();
  392. if (!this.checkBucketExist(minioProperties.getBucketName())) {
  393. this.createBucket(minioProperties.getBucketName());
  394. }
  395. }
  396. if (!this.checkBucketExist(bucketName)) {
  397. throw new RuntimeException("当前操作的桶不存在!");
  398. }
  399. String minioFilename = UUID.randomUUID().toString() + "_" + file.getName();//获取文件名称
  400. String fileType = minioFilename.substring(minioFilename.lastIndexOf(".") + 1);
  401. minioClient.uploadObject(
  402. UploadObjectArgs.builder()
  403. .bucket(bucketName)
  404. .object(minioFilename)//文件存储在minio中的名字
  405. .filename(filePath)//上传本地文件存储的路径
  406. .contentType(fileType)//文件类型
  407. .build());
  408. return this.getBucketFileExist(minioFilename, bucketName);
  409. }
  410. /**
  411. * 文件下载,通过http返回,即在浏览器下载
  412. *
  413. * @param response http请求的响应对象
  414. * @param bucketName 下载指定服务器的桶名称
  415. * @param objectName 下载的文件名称
  416. */
  417. public void downloadFile(HttpServletResponse response, String bucketName, String objectName) throws Exception {
  418. if (response == null || !StringUtils.hasLength(bucketName) || !StringUtils.hasLength(objectName)) {
  419. throw new RuntimeException("下载文件参数不全!");
  420. }
  421. if (!this.checkBucketExist(bucketName)) {
  422. throw new RuntimeException("当前操作的桶不存在!");
  423. }
  424. //获取一个下载的文件输入流操作
  425. GetObjectResponse objectResponse = minioClient.getObject(
  426. GetObjectArgs.builder()
  427. .bucket(bucketName)
  428. .object(objectName)
  429. .build());
  430. OutputStream outputStream = response.getOutputStream();
  431. int len = 0;
  432. byte[] buf = new byte[1024 * 8];
  433. while ((len = objectResponse.read(buf)) != -1) {
  434. outputStream.write(buf, 0, len);
  435. }
  436. if (outputStream != null) {
  437. outputStream.close();
  438. outputStream.flush();
  439. }
  440. objectResponse.close();
  441. }
  442. /**
  443. * 文件下载到指定路径
  444. *
  445. * @param downloadPath 下载到本地路径
  446. * @param bucketName 下载指定服务器的桶名称
  447. * @param objectName 下载的文件名称
  448. */
  449. public void downloadPath(String downloadPath, String bucketName, String objectName) throws Exception {
  450. if (downloadPath.isEmpty() || !StringUtils.hasLength(bucketName) || !StringUtils.hasLength(objectName)) {
  451. throw new RuntimeException("下载文件参数不全!");
  452. }
  453. if (!new File(downloadPath).isDirectory()) {
  454. throw new RuntimeException("本地下载路径必须是一个文件夹或者文件路径!");
  455. }
  456. if (!this.checkBucketExist(bucketName)) {
  457. throw new RuntimeException("当前操作的桶不存在!");
  458. }
  459. downloadPath += objectName;
  460. minioClient.downloadObject(
  461. DownloadObjectArgs.builder()
  462. .bucket(bucketName) //指定是在哪一个桶下载
  463. .object(objectName)//是minio中文件存储的名字;本地上传的文件是user.xlsx到minio中存储的是user-minio,那么这里就是user-minio
  464. .filename(downloadPath)//需要下载到本地的路径,一定是带上保存的文件名;如 d:\\minio\\user.xlsx
  465. .build());
  466. }
  467. }

6.对上面封装的方法进行验证

可以在controller中写http接口来进行验证,本文采用的单元测试进行验证。

  1. package com.jdh.minio.config;
  2. import io.minio.*;
  3. import io.minio.messages.Bucket;
  4. import io.minio.messages.Item;
  5. import org.junit.jupiter.api.Test;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.boot.test.context.SpringBootTest;
  8. import org.springframework.mock.web.MockMultipartFile;
  9. import org.springframework.web.multipart.MultipartFile;
  10. import org.springframework.web.multipart.commons.CommonsMultipartFile;
  11. import java.io.*;
  12. import java.util.List;
  13. import static org.junit.jupiter.api.Assertions.*;
  14. @SpringBootTest
  15. class MinioFileUtilTest {
  16. @Autowired
  17. private MinioFileUtil minioFileUtil;
  18. /**
  19. * 创建一个桶
  20. */
  21. @Test
  22. void createBucket() throws Exception {
  23. minioFileUtil.createBucket("minio-file");
  24. /**
  25. 这里创建桶的命名规则在默认情况下有要求
  26. 用于存储 CloudTrail 日志文件的 Amazon S3 存储桶的名称必须符合非美国标准区域的命名要求。
  27. Amazon S3 存储桶的命名需符合以下一个或多个规则(用句点分隔开):
  28. 1.存储桶名称的长度介于 363 个字符之间,并且只能包含小写字母、数字、句点和短划线。
  29. 2.存储桶名称中的每个标签必须以小写字母或数字开头。
  30. 3.存储桶名称不能包含下划线、以短划线结束、包含连续句点或在句点旁边使用短划线。
  31. 4.存储桶名称不能采用 IP 地址格式 (198.51.100.24)。
  32. */
  33. boolean minioFile = minioFileUtil.checkBucketExist("minio-file");
  34. System.out.println(minioFile);
  35. }
  36. /**
  37. * 创建一个桶
  38. */
  39. @Test
  40. void createBucketByRegion() throws Exception {
  41. minioFileUtil.createBucketByRegion("minio-file", "minio-region");
  42. boolean minioFile = minioFileUtil.checkBucketExist("minio-file");
  43. System.out.println(minioFile);
  44. }
  45. /**
  46. * 删除一个桶
  47. */
  48. @Test
  49. void deleteBucket() throws Exception {
  50. minioFileUtil.deleteBucket("minio-file");
  51. boolean minioFile = minioFileUtil.checkBucketExist("minio-file");
  52. System.out.println(minioFile);
  53. }
  54. /**
  55. * 检测桶是否存在
  56. */
  57. @Test
  58. void checkBucketExist() throws Exception {
  59. boolean test = minioFileUtil.checkBucketExist("test");
  60. System.out.println(test);
  61. }
  62. /**
  63. * 获取所有的桶信息
  64. */
  65. @Test
  66. void getAllBucketInfo() throws Exception {
  67. List<Bucket> allBucketName = minioFileUtil.getAllBucketInfo();
  68. allBucketName.forEach(e -> System.out.println(e.name()));
  69. }
  70. /**
  71. * 获取某个桶中的全部文件
  72. */
  73. @Test
  74. void getBucketAllFile() throws Exception {
  75. Iterable<Result<Item>> allFile = minioFileUtil.getBucketAllFile("minio-folder", "part", true);
  76. for (Result<Item> result : allFile) {
  77. Item item = result.get();
  78. System.out.println(item.objectName());
  79. }
  80. }
  81. /**
  82. * 检测某个桶中是否存在某个文件
  83. */
  84. @Test
  85. void getBucketFileExist() throws Exception {
  86. boolean fileExist = minioFileUtil.getBucketFileExist("8aa570f9-53f5-4cb5-a0d1-c122ef4e3f89_出师表.docx", "minio-bucket");
  87. System.out.println(fileExist);
  88. }
  89. /**
  90. * 删除桶中的一个文件
  91. *
  92. * @throws Exception
  93. */
  94. @Test
  95. void deleteBucketFile() throws Exception {
  96. Boolean b = minioFileUtil.deleteBucketFile("minio-folder", "出师表.docx");
  97. System.out.println(b);
  98. }
  99. /**
  100. * 删除桶中的一个文件夹
  101. *
  102. * @throws Exception
  103. */
  104. @Test
  105. void deleteBucketFolder() throws Exception {
  106. boolean b = minioFileUtil.deleteBucketFolder("minio-folder", "tempFile", true);
  107. System.out.println(b);
  108. }
  109. /**
  110. * 获取文件下载路径
  111. */
  112. @Test
  113. void getFileDownloadUrl() throws Exception {
  114. String fileUrl = minioFileUtil.getFileDownloadUrl("minio-bucket", "出师表.docx", 60);
  115. System.out.println(fileUrl);
  116. }
  117. /**
  118. * 获取文件上传路径
  119. */
  120. @Test
  121. void getFileUploadUrl() throws Exception {
  122. String fileUrl = minioFileUtil.getFileUploadUrl("minio-bucket", "出师表1.docx", 3600);
  123. System.out.println(fileUrl);
  124. }
  125. /**
  126. * 在一个桶中创建一个空文件夹
  127. *
  128. * @throws Exception
  129. */
  130. @Test
  131. void createBucketFolder() throws Exception {
  132. String buckName = "minio-bucket";
  133. String folderName = "part";
  134. ObjectWriteResponse bucketFolder = minioFileUtil.createBucketFolder(buckName, folderName);
  135. }
  136. /**
  137. * 在一个桶中创建一个空文件夹
  138. *
  139. * @throws Exception
  140. */
  141. @Test
  142. void checkBucketFolderExist() throws Exception {
  143. Boolean tempFile = minioFileUtil.checkBucketFolderExist("minio-bucket", "down", true);
  144. System.out.println(tempFile);
  145. }
  146. /**
  147. * 文件上传,通过MultipartFile形式
  148. */
  149. @Test
  150. void uploadFile() throws Exception {
  151. File file = new File("D:\\file\\出师表.docx");
  152. FileInputStream fileInputStream = new FileInputStream(file);
  153. String fileName = file.getName();
  154. MockMultipartFile multipartFile = new MockMultipartFile(fileName, fileName, "docx", fileInputStream);
  155. boolean uploadFile = minioFileUtil.uploadFile(multipartFile, "minio-folder");
  156. System.out.println(uploadFile);
  157. }
  158. /**
  159. * 文件上传,通过本地路径
  160. *
  161. * @throws Exception
  162. */
  163. @Test
  164. void uploadPath() throws Exception {
  165. boolean uploadPath = minioFileUtil.uploadPath("D:\\file\\出师表.docx", "minio-bucket");
  166. System.out.println(uploadPath);
  167. }
  168. /**
  169. * 文件下载,通过http响应下载
  170. */
  171. @Test
  172. void downloadFile() {
  173. //这里可以使用模拟请求来验证
  174. }
  175. /**
  176. * 文件下载,通过路径直接下载到本地
  177. *
  178. * @throws Exception
  179. */
  180. @Test
  181. void downloadPath() throws Exception {
  182. MinioClient client = minioFileUtil.getClient();
  183. minioFileUtil.downloadPath("D:\\file\\", "minio-bucket", "8aa570f9-53f5-4cb5-a0d1-c122ef4e3f89_出师表.docx");
  184. }
  185. }

7.验证结果

通过访问minio的服务端界面查看功能是否验证通过

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/577377
推荐阅读
相关标签
  

闽ICP备14008679号