简介
MinIO是一个高性能的开源对象存储系统,致力于提供高性能、可伸缩、安全的数据存储解决方案。
背景
积累知识。
教程
1、pom依赖
<!--minio文件服务器-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
<optional>true</optional>
</dependency>
<!--代码简化工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!--Hutool工具-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.22</version>
</dependency>
2、yml文件配置
minio:
# 访问路径
endpoint: http://ip:port
# 账户
accessKey: admin
# 密钥
secretKey: minio
# 桶名
bucket-name: bucketName
3、属性类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Minio属性配置
* @author ClancyLv
* @date 2023/6/19 15:20
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
/**
* minio路径
*/
private String endpoint;
/**
*账户
*/
private String accessKey;
/**
* 密钥
*/
private String secretKey;
/**
*桶名
*/
private String bucketName;
}
4、配置类
import cn.hutool.core.util.StrUtil;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* minio工具:文件处理
* @author ClancyLv
* @date 2023/6/19 15:13
*/
@Slf4j
@Configuration
public class MinioTemplate {
// minio客户端
private final MinioClient minioClient;
// 桶名
private final String bucketName;
/**
* minio初始化
*/
@SneakyThrows
public MinioTemplate(MinioProperties minioProperties) {
this.minioClient = new MinioClient(minioProperties.getEndpoint(), minioProperties.getAccessKey(), minioProperties.getSecretKey());
this.bucketName = minioProperties.getBucketName();
}
/**
* 判断bucket是否存在
* @return 布尔
*/
public boolean bucketExists() {
try {
return minioClient.bucketExists(bucketName);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 创建桶
*/
public void makeBucket() {
try {
boolean isExist = bucketExists();
if (!isExist) {
minioClient.makeBucket(bucketName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件服务器所有桶名称
* @return 桶名称列表
*/
@SneakyThrows
public List<String> listBucketNames() {
List<Bucket> bucketList = minioClient.listBuckets();
List<String> bucketListName = new ArrayList<>();
for (Bucket bucket : bucketList) {
bucketListName.add(bucket.name());
}
return bucketListName;
}
/**
* 上传文件(不指定Content-Type)
* @param objectName 文件名称
* @param inputStream 文件输入流
*/
@SneakyThrows
public void putObject(String objectName, InputStream inputStream) {
putObject(objectName, inputStream, null);
}
/**
* 上传文件(指定Content-Type)
* @param objectName 文件名称
* @param inputStream 文件输入流
* @param contentType 文件类型
*/
@SneakyThrows
public void putObject(String objectName, InputStream inputStream, String contentType) {
if (!this.bucketExists()) {
this.makeBucket();
}
//上传文件到指定目录
PutObjectOptions options = new PutObjectOptions(-1, PutObjectOptions.MIN_MULTIPART_SIZE);
// 增加文件类型
if (StrUtil.isNotBlank(contentType)) {
options.setContentType(contentType);
}
minioClient.putObject(bucketName, objectName, inputStream, options);
// 关闭流
inputStream.close();
}
/**
* 获取文件
* @param objectName 文件名称
* @return 文件流
*/
public InputStream getObject(String objectName) {
InputStream inputStream;
try {
inputStream = minioClient.getObject(bucketName, objectName);
return inputStream;
} catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidBucketNameException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException e) {
e.printStackTrace();
}
return null;
}
/**
* 根据文件前缀模糊获取文件列表
* @param prefix 文件前缀
* @param recursive 是否递归查询
* @return 文件列表
*/
public List<Item> getAllObjectsByPrefix(String prefix, boolean recursive) throws Exception {
List<Item> objectList = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = minioClient.listObjects(bucketName, prefix, recursive);
for (Result<Item> itemResult : objectsIterator) {
objectList.add(itemResult.get());
}
return objectList;
}
/**
* 获取文件外链
* @param objectName 文件名称
* @param expiry 过期时间
* @return 链接
*/
@SneakyThrows
public String getPresignedObjectUrl(String objectName, Integer expiry) {
expiry = expiryHandle(expiry);
return minioClient.getPresignedObjectUrl(Method.GET, bucketName, objectName, expiry, new HashMap<>());
}
private static int expiryHandle(Integer expiry) {
expiry = expiry * 60;
if (expiry > 604800) {
return 604800;
}
return expiry;
}
/**
* 删除单个文件
* @param objectName 文件名
*/
public void removeObject(String objectName) {
try {
boolean isExist = bucketExists();
if (isExist) {
minioClient.removeObject(bucketName, objectName);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除多个文件
* @param objectNames 文件名列表
*/
public void removeObjects(List<String> objectNames) {
try {
boolean isExist = bucketExists();
if (isExist) {
Iterable<Result<DeleteError>> results = minioClient.removeObjects(bucketName, objectNames);
// 需要遍历返回结果才能删除成功
for (Result<DeleteError> result : results) {
DeleteError deleteError = result.get();
log.error("Error in deleting object " + deleteError.objectName() + "; " + deleteError.message());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}