package com.ming.utils;
import io.minio.*;
import io.minio.Result;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Description minio 单例模式 工具类型、
* Create By Mr.Fang
*
* @time 2022/7/10 9:57
**/
public class MinioUtils {
private static MinioUtils minioUtils = new MinioUtils();
private MinioClient minioClient;
private static final String endpoint = "http://xxx.xxx.xxx.xx:9000";
private static final String accessKey = "xxxxxx"; // 你的 key
private static final String secretKey = "xxxxxxxxxxxx"; //你的 secret
private String bucketName = "xxxx"; //桶名称
private MinioUtils() {
this.init();
}
/**
* 初始化创建对象
*/
private void init() {
minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey).build();
}
/**
* Description 获取 MinioUtils 对象
* Create By Mr.Fang
*
* @return com.ming.utils.MinioUtils
* @time 2022/7/10 10:18
**/
public static MinioUtils getInstance() {
return minioUtils;
}
/**
* Description 获取 MinioClient 对象
* Create By Mr.Fang
*
* @return com.ming.utils.MinioUtils
* @time 2022/7/10 10:18
**/
public MinioClient getMinioClient() {
return minioClient;
}
/**
* 设置 桶名称
*
* @param bucketName
*/
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
/**
* Description 判断桶是否存在
* Create By Mr.Fang
*
* @param bucket
* @return java.lang.Boolean
* @time 2022/7/10 9:57
**/
public Boolean existBucket(String bucket) {
try {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* Description 创建一个桶
* Create By Mr.Fang
*
* @param bucket 桶名称
* @return java.lang.Boolean
* @time 2022/7/10 9:56
**/
public Boolean createBucket(String bucket) {
try {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Description 上传本地文件
* Create By Mr.Fang
*
* @param path 本地文件路径
* @param object 文件名
* @return java.lang.Boolean
* @time 2022/7/10 9:55
**/
public Boolean uploadObject(String path, String object) {
try {
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket(bucketName)
.object(object)
.filename(path)
.build());
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
/**
* Description 以流的方式上传文件
* Create By Mr.Fang
*
* @param in input 流
* @param object 文件名
* @param size 文件大小
* @return java.lang.Boolean
* @time 2022/7/10 9:55
**/
public Boolean uploadObject(InputStream in, String object, Long size) {
try {
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(object)
.stream(in, size, -1)
.build()
);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Description 多文件上传
* Create By Mr.Fang
*
* @param objects SnowballObject对象
* @return java.lang.Boolean
* @Param
* @time 2022/7/10 10:24
**/
public Boolean uploadsObject(List<SnowballObject> objects) {
try {
minioClient.uploadSnowballObjects(
UploadSnowballObjectsArgs.builder().bucket(bucketName).objects(objects).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Description 批量删除文件对象
* Create By Mr.Fang
*
* @param objects 文件名称或完整文件路径
* @return java.util.List<io.minio.messages.DeleteError>
* @time 2022/7/10 9:54
**/
public List<DeleteError> deleteObject(List<String> objects) {
List<DeleteError> deleteErrors = new ArrayList<>();
List<DeleteObject> deleteObjects = objects.stream().map(value -> new DeleteObject(value)).collect(Collectors.toList());
Iterable<Result<DeleteError>> results =
minioClient.removeObjects(
RemoveObjectsArgs
.builder()
.bucket(bucketName)
.objects(deleteObjects)
.build());
try {
for (Result<DeleteError> result : results) {
DeleteError error = result.get();
deleteErrors.add(error);
}
} catch (Exception e) {
e.printStackTrace();
}
return deleteErrors;
}
/**
* Description 下载文件到本地
* Create By Mr.Fang
*
* @param object 文件名
* @param output 输出路径
* @return void
* @time 2022/7/10 9:53
**/
public void download(String object, String output) {
try {
minioClient.downloadObject(
DownloadObjectArgs.builder()
.bucket(bucketName)
.object(object)
.filename(output)
.build());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Description 下载 minio文件,返回流的方式,同时支持在线预览
* Create By Mr.Fang
*
* @param object 文件名称
* @param isOnline 是否在线预览,不同文件类型请修改 setContentType
* @param response 响应对象
* @return void
* @time 2022/7/10 9:51
**/
public void download(String object, Boolean isOnline, HttpServletResponse response) {
try (InputStream stream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(object)
.build())) {
try {
BufferedInputStream br = new BufferedInputStream(stream);
byte[] buf = new byte[1024];
int len = 0;
response.reset(); // 非常重要
if (Objects.nonNull(isOnline) && isOnline) { // 在线打开方式
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=" + object);
} else { // 纯下载方式
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename=" + object);
}
OutputStream out = response.getOutputStream();
while ((len = br.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.flush();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Description 获取所有桶
* Create By Mr.Fang
*
* @return java.util.List<io.minio.messages.Bucket>
* @time 2022/7/10 9:50
**/
public List<Bucket> listBuckets() {
try {
return minioClient.listBuckets();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Description 文件列表
* Create By Mr.Fang
*
* @param limit 范围 1-1000
* @return java.util.List<io.minio.messages.Item>
* @time 2022/7/10 9:50
**/
public List<Item> listObjects(int limit) {
List<Item> objects = new ArrayList<>();
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder()
.bucket(bucketName)
.maxKeys(limit)
.includeVersions(true)
.build());
try {
for (Result<Item> result : results) {
objects.add(result.get());
}
} catch (Exception e) {
e.printStackTrace();
}
return objects;
}
/**
* Description 生成预览链接,最大7天有效期;
* 如果想永久有效,在 minio 控制台设置仓库访问规则总几率
* Create by Mr.Fang
*
* @param object 文件名称
* @param contentType 预览类型 image/gif", "image/jpeg", "image/jpg", "image/png", "application/pdf
* @return java.lang.String
* @Time 9:43 2022/7/10
* @Params
**/
public String getPreviewUrl(String object, String contentType) {
Map<String, String> reqParams = new HashMap<>();
reqParams.put("response-content-type", contentType != null ? contentType : "application/pdf");
String url = null;
try {
url = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(object)
.expiry(7, TimeUnit.DAYS)
.extraQueryParams(reqParams)
.build());
} catch (Exception e) {
e.printStackTrace();
}
return url;
}
/**
* Description 网络文件转储 minio
* Author Mr.Fang
*
* @param httpUrl 文件地址
* @return void
* @Time 9:42 2022/7/10
* @Params
**/
public void netToMinio(String httpUrl) {
int i = httpUrl.lastIndexOf(".");
String substring = httpUrl.substring(i);
URL url;
try {
url = new URL(httpUrl);
URLConnection urlConnection = url.openConnection();
// agent 模拟浏览器
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
DataInputStream dataInputStream = new DataInputStream(url.openStream());
// 临时文件转储
File tempFile = File.createTempFile(UUID.randomUUID().toString().replace("-", ""), substring);
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = dataInputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
fileOutputStream.write(output.toByteArray());
// 上传minio
uploadObject(tempFile.getAbsolutePath(), tempFile.getName());
dataInputStream.close();
fileOutputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Description 文件转字节数组
* Create By Mr.Fang
*
* @param path 文件路径
* @return byte[] 字节数组
* @time 2022/7/10 10:55
**/
public byte[] fileToBytes(String path) {
FileInputStream fis = null;
ByteArrayOutputStream bos = null;
try {
bos = new ByteArrayOutputStream();
fis = new FileInputStream(path);
int temp;
byte[] bt = new byte[1024 * 10];
while ((temp = fis.read(bt)) != -1) {
bos.write(bt, 0, temp);
}
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (Objects.nonNull(fis)) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return bos.toByteArray();
}
public static void main(String[] args) throws Exception {
MinioUtils minioUtils = MinioUtils.getInstance();
// 多文件上传示例
List<SnowballObject> objects = new ArrayList<>();
byte[] bytes1 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\1.png");
byte[] bytes2 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\2.png");
byte[] bytes3 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\3.png");
objects.add(new SnowballObject("1.png", new ByteArrayInputStream(bytes1), bytes1.length, ZonedDateTime.now()));
objects.add(new SnowballObject("2.png", new ByteArrayInputStream(bytes2), bytes2.length, ZonedDateTime.now()));
objects.add(new SnowballObject("3.png", new ByteArrayInputStream(bytes3), bytes3.length, ZonedDateTime.now()));
minioUtils.uploadsObject(objects);
}
}
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>