package com.cdzy.operations.utils; import io.minio.*; import io.minio.http.Method; import io.minio.messages.Bucket; import jakarta.annotation.Resource; import lombok.Getter; import lombok.Setter; import org.springframework.stereotype.Component; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Component public class MinioUtil { @Getter @Setter private static String baseUrl; @Getter @Setter private static String bucketName; @Resource private MinioClient minioClient; /** * 创建桶 * @param bucket 数据桶名称 * @throws Exception 异常 */ public void createBucket(String bucket) throws Exception { //查看桶是否存在 boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build()); if (!exists){ minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build()); } } /** * 上传文件 * @param inputStream 文件流 * @param bucket 数据桶名称 * @param objectName 文件名称 * @throws Exception 异常 */ public void uploadFile(InputStream inputStream, String bucket, String objectName) throws Exception{ //上传文件 minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName) .stream(inputStream,-1,Integer.MAX_VALUE).build()); } /** * 上传文件至默认桶内 * @param inputStream 文件流 * @param objectName 文件名称 * @throws Exception 异常 */ public void uploadFile(InputStream inputStream, String objectName) throws Exception{ //上传文件 uploadFile(inputStream, bucketName, objectName); } /** * 获取文件分析连接(7天有效 * @param bucket 数据桶名称 * @param fileName 文件名称 * @return url * @throws Exception 异常 */ public String getFileUrl(String bucket, String fileName) throws Exception { return minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(bucket) .object(fileName) .expiry(7, TimeUnit.DAYS) // 有效期7天 .build() ); } /** * 获取默认桶内文件分析连接(7天有效 * @param fileName 文件名称 * @return url * @throws Exception 异常 */ public String getFileUrl(String fileName) throws Exception { return minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(bucketName) .object(fileName) .expiry(7, TimeUnit.DAYS) // 有效期7天 .build() ); } /** * 获取所有的桶 * @return 数据桶名称列表 * @throws Exception 异常 */ public List getAllBucket() throws Exception{ List buckets = minioClient.listBuckets(); return buckets.stream().map(Bucket::name).collect(Collectors.toList()); } /** * 下载文件 * @param bucket 数据桶名称 * @param objectName 文件名称 * @return 文件流 * @throws Exception 异常 */ public InputStream downLoad(String bucket,String objectName) throws Exception{ return minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build()); } /** * 下载默认桶内文件 * @param objectName 文件名称 * @return 文件流 * @throws Exception 异常 */ public InputStream downLoad(String objectName) throws Exception{ return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); } /** * 删除桶 * @param bucket 数据桶名称 * @throws Exception 异常 */ public void deleteBucket(String bucket) throws Exception{ minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build()); } /** * 删除文件 * @param bucket 数据桶名称 * @param objectName 文件名称 * @throws Exception 异常 */ public void deleteObject(String bucket,String objectName) throws Exception{ minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build()); } /** * 删除默认桶内文件 * @param objectName 文件名称 * @throws Exception 异常 */ public void deleteObject(String objectName) throws Exception{ minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build()); } /** * 批量上传文件(原子性操作) * @param fileStreams 文件流列表 * @param bucket 数据桶名称 * @param objectNames 文件名列表 * @return 是否全部成功 * @throws Exception 异常 */ public boolean batchUploadFiles(List fileStreams, String bucket, List objectNames) throws Exception { if (fileStreams.size() != objectNames.size()) { throw new IllegalArgumentException("文件流和文件名数量不匹配"); } List successUploads = new ArrayList<>(); try { // 确保桶存在 createBucket(bucket); // 逐个上传文件 for (int i = 0; i < fileStreams.size(); i++) { String objectName = objectNames.get(i); InputStream inputStream = fileStreams.get(i); minioClient.putObject(PutObjectArgs.builder() .bucket(bucket) .object(objectName) .stream(inputStream, -1, Integer.MAX_VALUE) .build()); // 记录成功上传的文件 successUploads.add(objectName); } return true; } catch (Exception e) { // 回滚:删除已上传的文件 rollbackBatchUpload(bucket, successUploads); throw new Exception("批量上传失败,已回滚", e); } } /** * 回滚批量上传操作 * @param bucket 数据桶名称 * @param objectNames 需要删除的文件名列表 */ private void rollbackBatchUpload(String bucket, List objectNames) { if (objectNames.isEmpty()) { return; } for (String objectName : objectNames) { try { minioClient.removeObject(RemoveObjectArgs.builder() .bucket(bucket) .object(objectName) .build()); } catch (Exception rollbackException) { // 记录回滚失败,但不影响主流程 System.err.println("回滚删除文件失败: " + objectName + ", 错误: " + rollbackException.getMessage()); } } } /** * 批量上传到默认桶 */ public boolean batchUploadFiles(List fileStreams, List objectNames) throws Exception { return batchUploadFiles(fileStreams, bucketName, objectNames); } /** * 获取MinIO中指定文件的文件流 * @param bucket 数据桶名称 * @param objectName 文件名称 * @return 文件流 * @throws Exception 异常 */ public InputStream getFileStream(String bucket, String objectName) throws Exception { return minioClient.getObject( GetObjectArgs.builder() .bucket(bucket) .object(objectName) .build() ); } /** * 获取默认桶中文件的文件流 * @param objectName 文件名称 * @return 文件流 * @throws Exception 异常 */ public InputStream getFileStream(String objectName) throws Exception { return minioClient.getObject( GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .build() ); } /** * 获取二维码展示路径 * @param objectName 文件名称 */ public String getShowUrl(String objectName){ return baseUrl+objectName; } }