package top.lifuquan.dao; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import org.springframework.stereotype.Repository; import org.springframework.web.multipart.MultipartFile; import io.minio.BucketExistsArgs; import io.minio.GetPresignedObjectUrlArgs; import io.minio.ListObjectsArgs; import io.minio.MakeBucketArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.Result; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.Item; import lombok.extern.slf4j.Slf4j; import top.lifuquan.exception.minio.MinioClientGetFailed; import top.lifuquan.exception.minio.MinioClientPutFailed; @Slf4j @Repository public class MinioDao { private final MinioClient minioClient; public MinioDao(MinioClient minioClient) { this.minioClient = minioClient; log.info("已完成{}装配", this.getClass().getName()); } /* * 获取文件名列表 */ public List listFileNames(String bucketName) throws MinioClientGetFailed { return listFileNames(bucketName, null); } /* * 获取文件名列表 */ public List listFileNames(String bucketName, String prefix) throws MinioClientGetFailed { Iterable> results = minioClient .listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).build()); List result = new ArrayList<>(); try { for (Result item : results) { result.add(item.get().objectName()); } } catch (Exception e) { // result.get() 异常 e.printStackTrace(); throw new MinioClientGetFailed("通过bucket名称 {} 获取内部元素列表失败", bucketName); } return result; } /* * 通过bucket名称打印元素列表 */ public void printItemsByBucketName(String bucketName) throws MinioClientGetFailed { Iterable> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); Item item; try { for (Result result : results) { item = result.get(); // 路径有很多属性是null if (item.isDir()) { log.info("路径--属性打印-------- objectName: {}-- size:{}-- owner:{}-- isLatest:{}-- isDir:{}", item.objectName(), item.size(), item.owner(), item.isLatest(), item.isDir()); } else { log.info("元素--属性打印-------- objectName: {}-- lastModified:{}-- etag:{}-- size:{}--" + " storageClass:{}-- owner:{}-- userMetadata:{}-- isLatest:{}--" + " versionId:{}-- isDir:{}-- isDeleteMarker:{}", item.objectName(), item.lastModified(), item.etag(), item.size(), item.storageClass(), item.owner().displayName(), item.userMetadata(), item.isLatest(), item.versionId(), item.isDir(), item.isDeleteMarker()); } } } catch (Exception e) { // result.get() 异常 e.printStackTrace(); throw new MinioClientGetFailed("通过bucket名称 {} 获取内部元素列表失败", bucketName); } } /* * 获取全部的bucket名称 */ public List listBucketNames() throws MinioClientGetFailed { try { List buckets = minioClient.listBuckets(); List result = new ArrayList<>(); for (Bucket bucket : buckets) { result.add(bucket.name()); } return result; } catch (Exception e) { e.printStackTrace(); throw new MinioClientGetFailed("获取bucket列表失败"); } } /* * 上传文件 * 自动添加日期,格式20221109/ * prefix为null 最终格式 20221109/fileName * prefix为abc 最终格式为 abc/20221109/fileName * minio上传完全相同路径文件会覆盖,在文件名之前加上一个uuid字符串 * 返回文件在bucket中的完整路径 */ public String upload(MultipartFile file, String bucketName, String prefix) { // 在原始文件基础上添加日期和前缀 String filePath; DateFormat format = new SimpleDateFormat("yyyyMMdd/"); String uuid = UUID.randomUUID().toString().replace("-", ""); if (prefix != null) { prefix = prefix.endsWith("/") ? prefix : prefix + "/"; filePath = prefix + format.format(System.currentTimeMillis()) + uuid + "-" + file.getOriginalFilename(); } else { filePath = format.format(System.currentTimeMillis()) + uuid + "-" + file.getOriginalFilename(); } PutObjectArgs args; try { args = PutObjectArgs .builder() .bucket(bucketName) .object(filePath) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build(); minioClient.putObject(args); return filePath; } catch (Exception e) { // file.getInputStream() 异常 IOException // minioClient.putObject(args) 异常 一大堆 e.printStackTrace(); return null; } } /* * 获取download链接,默认7天有效 */ public String download(String bucketName, String filePath) { GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs .builder() .method(Method.GET) .bucket(bucketName) .object(filePath) .expiry(7, TimeUnit.DAYS) .build(); try { return minioClient.getPresignedObjectUrl(args); } catch (Exception e) { e.printStackTrace(); } return null; } /* * 检查bucket是否存在 */ public boolean bucketExists(String bucketName) throws Exception { try { return minioClient.bucketExists(BucketExistsArgs .builder() .bucket(bucketName) .build()); } catch (IllegalArgumentException e) { throw new MinioClientGetFailed("输入的bucketName--{}--不符合Amazon S3规范: {}", bucketName, e.getMessage()); } catch (Exception e) { e.printStackTrace(); throw new MinioClientGetFailed("查询BucketExists出错--{}--{}", bucketName, e.getMessage()); } } /* * 创建bucket */ public void makeBucket(String bucketName) throws Exception { try { minioClient.makeBucket(MakeBucketArgs .builder() .bucket(bucketName) .build()); } catch (IllegalArgumentException e) { e.printStackTrace(); throw new MinioClientPutFailed("输入的bucketName--{}--不符合Amazon S3规范: {}", bucketName, e.getMessage()); } catch (Exception e) { e.printStackTrace(); throw new MinioClientPutFailed("Bucket--{}--创建失败", bucketName); } } }