# MinIO

# 1. 介绍

说明:

  • 对象存储(Object Storage)
  • 开源GNU AGPL v3 (完全免费)

官网:

  • https://min.io/
  • http://minio.org.cn/

# 2. windows 上安装与启动

下载:

  • windows 版本,历史版本: https://dl.min.io/server/minio/release/windows-amd64/archive/
  • 2025-04-22 版本:
    • https://dl.min.io/server/minio/release/windows-amd64/archive/minio.RELEASE.2025-04-22T22-12-26Z
    • 该版本最后一个保留 web 控制台的版本
    • minio.RELEASE.2025-04-22T22-12-26Z 改为 minio.exe

目录:

D:\download\minio
  data/
  minio.exe

启动:

D:\download\minio>minio.exe server ./data --console-address ":9001"
MinIO Object Storage Server
Copyright: 2015-2025 MinIO, Inc.
License: GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html
Version: RELEASE.2025-04-22T22-12-26Z (go1.24.2 windows/amd64)

API: http://192.168.1.105:9000  http://127.0.0.1:9000
   RootUser: minioadmin
   RootPass: minioadmin

WebUI: http://192.168.1.105:9001  http://127.0.0.1:9001
   RootUser: minioadmin
   RootPass: minioadmin

管理后台:

  • http://127.0.0.1:9001

# 命令行参数

服务 IP 和端口:

# 0.0.0.0:9000   所有 IP 都可以访问
minio server --address :9000 ./data

# 127.0.0.1:9000  这个 IP 才可以访问
minio server --address 127.0.0.1:9000 ./data

账号密码:

# 通过环境变量设置
# MINIO_ROOT_USER: 账号
# MINIO_ROOT_PASSWORD: 密码,最少 8 个字符
set MINIO_ROOT_USER=admin & set MINIO_ROOT_PASSWORD=12345678 & minio server --address :9000 ./data

管理界面 IP 和端口:

# 0.0.0.0:9001
minio server --console-address :9001 ./data

# 127.0.0.1:9001
minio server --console-address 127.0.0.1:9001 ./data

# 3. SpringBoot 操作 MinIO

# 3.1. 坐标

<dependency>
   <groupId>io.minio</groupId>
   <artifactId>minio</artifactId>
   <version>8.5.2</version>
</dependency>

# 3.2. IDE 中关联源码

下载源码: https://codeload.github.com/minio/minio-java/zip/refs/tags/8.5.2

源码位置: minio-java-8.5.2\api\src\main\java\io

# 3.3. 配置客户端

package org.example.config;

@Configuration
public class Config {
    // 单例, 线程安全
    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint("http://localhost:9000")

                // 使用默认 用户名、密码 可以登录
                .credentials("minioadmin", "minioadmin")

                .build();
    }
}

# 3.4. 使用客户端

@SpringBootTest
class ApplicationTests {
    @Autowired
    private MinioClient minioClient;

    @Test
    void testMinioClient() {
        System.out.println(minioClient);
    }
}

# 3.5. 桶(目录)操作

# 3.5.1. 是否存在

@Test
void testBucketIsExist() throws Exception{
   BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder()
            .bucket("my-folder-1")
            .build();

   boolean bucketExists = minioClient.bucketExists(bucketExistsArgs);

   System.out.println("bucketExists: " + bucketExists);
}

# 3.5.2. 创建

@Test
void testCreateBucket() throws Exception{
   MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder()
            .bucket("my-folder-1")
            .build();

   minioClient.makeBucket(makeBucketArgs);
}

# 3.5.3. 列表

@Test
void testListBucket() throws Exception{
   List<Bucket> buckets = minioClient.listBuckets();
   buckets.forEach(bucket -> System.out.println(bucket.name()));
}

# 3.5.4. 删除

@Test
void testRemoveBucket() throws Exception{
   RemoveBucketArgs removeBucketArgs = RemoveBucketArgs.builder()
            .bucket("my-folder-1")
            .build();
   minioClient.removeBucket(removeBucketArgs);
}

# 3.6. 对象(文件)操作

# 3.6.1. 是否存在

@Test
void testObjectIsExist() throws Exception{
   StatObjectArgs statObjectArgs = StatObjectArgs.builder()
            .bucket("my-folder-1")
            .object("1.txt")
            .build();
   // 查看文件的状态,文件不存在则报错
   StatObjectResponse statObjectResponse = minioClient.statObject(statObjectArgs);
   System.out.println(statObjectResponse);
}

# 3.6.2. 创建

@Test
void testPutObject() throws Exception{
   String content = "MinIO, 你好!";

   byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
   ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

   PutObjectArgs putObjectArgs = PutObjectArgs.builder()
            .bucket("my-folder-1")
            .object("1.txt")

            // 第 3 个参数,为缓冲区大小 
            .stream(byteArrayInputStream, bytes.length, -1)
            
            .build();

   minioClient.putObject(putObjectArgs);
}

# 3.6.3. 获取

@Test
void testGetObject() throws Exception{
   GetObjectArgs getObjectArgs = GetObjectArgs.builder()
            .bucket("my-folder-1")
            .object("1.txt")
            .build();

   // GetObjectResponse extends FilterInputStream
   //    FilterInputStream extends InputStream

   try (GetObjectResponse getObjectResponse = minioClient.getObject(getObjectArgs)) {
      byte[] byteArray = IOUtils.toByteArray(getObjectResponse);

      String content = new String(byteArray, StandardCharsets.UTF_8);

      System.out.println(content);
   }
}

# 3.6.4. 生成 URL

@Test
void testGetObjectUrl() throws Exception{
   GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder()
            .bucket("my-folder-1")
            .object("1.txt")
            .method(Method.GET) // Get 请求方式
            .expiry(10, TimeUnit.SECONDS) // 10 秒过期
            .build();

   String url = minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);

   System.out.println(url);
}

# 3.6.5. 列表

@Test
void testListObject() throws Exception{
   ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
            .bucket("my-folder-1")
            .build();
   Iterable<Result<Item>> results = minioClient.listObjects(listObjectsArgs);

   for (Result<Item> result : results) {
      System.out.println(result.get().objectName());
   }
}

# 3.6.6. 删除

@Test
void testRemoveObject() throws Exception{
   RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
            .bucket("my-folder-1")
            .object("1.txt")
            .build();
   minioClient.removeObject(removeObjectArgs);
}
本章目录