Minio是一个对象存储解决方案,非常适合于存储大容量非结构化的数据,可以充当文件服务器使用。

安装

window安装

1.下载minio的exe安装文件

1
https://dl.minio.org.cn/server/minio/release/windows-amd64/minio.exe

2.创建minio存储数据路径(在windows上创建一个文件即可)

3.创建minio启动脚本 start.bat

1
set MINIO_ROOT_USER=minioadmin&& set MINIO_ROOT_PASSWORD=123456789 && minio.exe server D:\work\Server\minio\data --address :9000 --console-address :9001

4.双击脚本即可启动minio

Docker安装

1.拉取minio镜像

1
docker pull minio/minio

2.创建挂载文件夹

1
2
mkdir -p /home/xlb/tool/minio/data
mkdir -p /home/xlb/tool/minio/config

3.命令启动容器

1
docker run -p 9000:9000 -p 9001:9001 --name minio -e MINIO_ROOT_USER=admin -e MINIO_ROOT_PASSWORD=minio123 -v /home/xlb/tool/minio/data:/data  -v /home/xlb/tool/minio/config:/root/.minio minio/minio server /data --console-address ":9001"

使用

开发环境构建

1.引入maven依赖

1
2
3
4
<dependency>  
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>

2.处理minio配置信息

1
2
3
4
5
minio:  
endpoint: http://218.77.59.1:29000/
user: uav-platform
password: Ztt@123.
bucketName: uav-platform
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Data  
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

/**
* MInio节点
*/
private String endpoint;

/**
* 用户名称
*/
private String user;

/**
* 密码
*/
private String password;

/**
* 桶名称
*/
private String bucketName;

}

3.创建Minio连接客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration  
public class MyMinioClient {

@Autowired
private MinioProperties minioProperties;

@Bean
public MinioClient minioClient() {
MinioClient minioClient = MinioClient.builder()
.endpoint(minioProperties.getEndpoint())
.credentials(minioProperties.getUser(), minioProperties.getPassword())
.build();
return minioClient;
}

}

常见用法

1.创建 bucket 桶

1
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());

2.判断 bucket 桶是否存在

1
minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());

3.删除 bucket 桶

1
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());

4.根据对象名称获取桶中指定文件的文件流

1
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());

5.使用MultipartFile进行文件上传

1
2
3
4
5
6
7
8
9
10
11
@SneakyThrows(Exception.class)
public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName, String contentType) {
@Cleanup InputStream inputStream = file.getInputStream();
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.contentType(contentType)
.stream(inputStream, inputStream.available(), -1)
.build());
}

6.图片上传

1
2
3
4
5
6
7
8
9
10
public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String imageName) {  
if (StringUtils.hasLength(imageBase64)) {
InputStream in = base64ToInputStream(imageBase64);
String newName = System.currentTimeMillis() + "_" + imageName + ".jpg";
String year = String.valueOf(LocalDate.now().getYear());
String month = String.valueOf(LocalDate.now().getMonth());
return uploadFile(bucketName, year + "/" + month + "/" + newName, in);
}
return null;
}

7.通过流上传文件

1
2
3
4
5
6
7
8
9
@SneakyThrows(Exception.class)  
public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) {
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, inputStream.available(), -1)
.build());
}

8.创建文件夹或目录

1
2
3
4
5
6
7
8
9
@SneakyThrows(Exception.class)  
public ObjectWriteResponse createDir(String bucketName, String objectName) {
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
.build());
}

9.获取文件信息(抛出异常说明文件不存在)

1
2
3
4
5
6
7
8
@SneakyThrows(Exception.class)
public String getFileStatusInfo(String bucketName, String objectName) {
return minioClient.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build()).toString();
}

10.删除文件

1
2
3
4
5
6
7
8
@SneakyThrows(Exception.class)  
public void removeFile(String bucketName, String objectName) {
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
}

11.获取文件外链

1
2
3
4
5
6
7
8
@SneakyThrows(Exception.class)  
public String getPresignedObjectUrl(String bucketName, String objectName) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object(objectName)
.method(Method.GET).build();
return minioClient.getPresignedObjectUrl(args);
}

12.获取文件外链(有效期 秒)

1
2
3
4
5
6
@SneakyThrows(Exception.class)  
public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs
.builder().expiry(expires).bucket(bucketName).object(objectName).build();
return minioClient.getPresignedObjectUrl(args);
}

13.获取文件上传凭证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@SneakyThrows(Exception.class)  
public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs
.builder().expiry(expires).bucket(bucketName).object(objectName).build();
return minioClient.getPresignedObjectUrl(args);
}

@Data
public class CredentialsDTO implements Serializable {

private static final long serialVersionUID = 1L;

private String endpoint;

private String accessKey;

private String secretKey;

private String securityToken;
}