• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

minio的基本使用——java

武飞扬头像
寒夜憨憨
帮助1

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

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

5.封装一些简单的方法

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

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

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

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

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

7.验证结果

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcabef
系列文章
更多 icon
同类精品
更多 icon
继续加载