MinIo工具包
MinIo工具包
- 概念
- 特性
- MinIo工具包
- POM
- MinioUtils
- BeanConfig
概念
MinIO 是在 GNU Affero 通用公共許可證 v3.0 下發布的高性能對象存儲。 它是與 Amazon S3 云存儲服務兼容的 API。 使用 MinIO 為機器學習、分析和應用程序數據工作負載構建高性能基礎架構。特性
本節選自官網介紹
MinIo工具包
POM
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.3.0</version> </dependency>MinioUtils
import com.alibaba.fastjson.JSONObject; import io.minio.*; import io.minio.errors.*; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.DeleteObject; import io.minio.messages.Item; import lombok.extern.slf4j.Slf4j; import org.springframework.web.multipart.MultipartFile;import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.time.ZonedDateTime; import java.util.*; import java.util.concurrent.TimeUnit;/*** @Author: zrs* @Date: 2020/12/01/10:02* @Description: Minio工具類*/ @Slf4j public class MinioUtils {private static MinioClient minioClient;private static String endpoint;private static String bucketName;private static String accessKey;private static String secretKey;private static String folder;private static final String SEPARATOR = "/";private MinioUtils() {}public MinioUtils(MinIoConfig minIoConfig) {MinioUtils.endpoint = minIoConfig.getEndpoint();MinioUtils.bucketName = minIoConfig.getBucketName();MinioUtils.accessKey = minIoConfig.getAccessKey();MinioUtils.secretKey = minIoConfig.getSecretKey();MinioUtils.folder = minIoConfig.getFolder();createMinioClient();}public MinioUtils(String endpoint, String bucketName, String accessKey, String secretKey, String folder) {MinioUtils.endpoint = endpoint;MinioUtils.bucketName = bucketName;MinioUtils.accessKey = accessKey;MinioUtils.secretKey = secretKey;MinioUtils.folder = folder;createMinioClient();}/*** 創建minioClient*/public void createMinioClient() {try {if (null == minioClient) {log.info("minioClient create start");minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();createBucket();log.info("minioClient create end");}} catch (Exception e) {log.error("連接MinIO服務器異常:{}", e);}}/*** 獲取上傳文件的基礎路徑** @return url*/public static String getBasisUrl() {return endpoint + SEPARATOR + bucketName + SEPARATOR;}//操作存儲桶/*** 初始化Bucket** @throws Exception 異常*/private static void createBucket()throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}/*** 驗證bucketName是否存在** @return boolean true:存在*/public static boolean bucketExists()throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());}/*** 創建bucket*/public static void createBucket(String bucketName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}/*** 獲取存儲桶策略* <p>* 名稱** @return json*/private JSONObject getBucketPolicy(String bucketName)throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InsufficientDataException, ErrorResponseException {String bucketPolicy = minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());return JSONObject.parseObject(bucketPolicy);}/*** 獲取全部bucket* <p>* <a href="https://docs.minio.io/cn/java-client-api-reference.html#listBuckets">listBuckets</a>*/public static List<Bucket> getAllBuckets()throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.listBuckets();}/*** 根據bucketName獲取信息*/public static Optional<Bucket> getBucket(String bucketName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();}/*** 根據bucketName刪除信息*/public static void removeBucket(String bucketName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}//操作文件對象/*** 判斷文件是否存在** @param objectName 文件名稱* @return true:存在*/public static boolean doesObjectExist(String objectName) {boolean exist = true;try {minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).build());} catch (Exception e) {exist = false;}return exist;}/*** 判斷文件夾是否存在** @param objectName 文件名稱(去掉/)* @return true:存在*/public static boolean doesFolderExist(String objectName) {boolean exist = false;try {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());for (Result<Item> result : results) {Item item = result.get();if (item.isDir() && objectName.equals(item.objectName())) {exist = true;}}} catch (Exception e) {exist = false;}return exist;}/*** 根據文件前置查詢文件** @param prefix 前綴* @param recursive 是否遞歸查詢* @return MinioItem 列表*/public static List<Item> getAllObjectsByPrefix(String prefix,boolean recursive)throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException,IOException, NoSuchAlgorithmException, ServerException, XmlParserException {List<Item> list = new ArrayList<>();Iterable<Result<Item>> objectsIterator = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());if (objectsIterator != null) {for (Result<Item> o : objectsIterator) {Item item = o.get();list.add(item);}}return list;}/*** 獲取文件流** @param objectName 文件名稱* @return 二進制流*/public static GetObjectResponse getObject(String objectName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).build());}/*** 斷點下載** @param objectName 文件名稱* @param offset 起始字節的位置* @param length 要讀取的長度* @return 流*/public InputStream getObject(String objectName, long offset, long length)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).offset(offset).length(length).build());}/*** 獲取路徑下文件列表** @param prefix 文件名稱* @param recursive 是否遞歸查找,如果是false,就模擬文件夾結構查找* @return 二進制流*/public static Iterable<Result<Item>> listObjects(String prefix,boolean recursive) {return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());}/*** 通過MultipartFile,上傳文件** @param file 文件* @param objectName 文件名稱*/public static ObjectWriteResponse putObject(MultipartFile file,String objectName, String contentType)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {InputStream inputStream = file.getInputStream();return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).contentType(contentType).stream(inputStream, inputStream.available(), -1).build());}/*** 上傳本地文件** @param objectName 文件名稱* @param fileName 本地文件路徑*/public static ObjectWriteResponse putObject(String objectName,String fileName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).filename(fileName).build());}/*** 通過流上傳文件** @param objectName 文件對象* @param inputStream 文件流*/public static ObjectWriteResponse putObject(String objectName,InputStream inputStream)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).stream(inputStream, inputStream.available(), -1).build());}/*** 創建文件夾或目錄** @param objectName 目錄路徑*/public static ObjectWriteResponse putDirObject(String objectName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).stream(new ByteArrayInputStream(new byte[]{}), 0, -1).build());}/*** 獲取文件信息, 如果拋出異常則說明文件不存在** @param objectName 文件名稱* @return*/public static StatObjectResponse statObject(String objectName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).build());}/*** 拷貝文件** @param objectName 文件名稱* @param srcBucketName 目標bucket名稱* @param srcObjectName 目標文件名稱*/public static ObjectWriteResponse copyObject(String objectName,String srcBucketName, String srcObjectName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {return minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).build()).bucket(srcBucketName).object(srcObjectName).build());}/*** 刪除文件** @param objectName 文件名稱*/public static void removeObject(String objectName)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(folder + SEPARATOR + objectName).build());}/*** 批量刪除文件** @param keys 需要刪除的文件列表* @return*/public static void removeObjects(List<String> keys) {List<DeleteObject> objects = new LinkedList<>();keys.forEach(s -> {objects.add(new DeleteObject(s));try {removeObject(s);} catch (Exception e) {log.error("批量刪除失敗!error:{}", e);}});}//操作Presigned/*** 獲取文件外鏈** @param objectName 文件名稱* @param expires 過期時間 <=7 秒級* @return url*/public static String getPresignedObjectUrl(String objectName,Integer expires)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, ServerException, InternalException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(folder + SEPARATOR + objectName).expiry(expires, TimeUnit.HOURS).build());}/*** 給presigned URL設置策略** @param objectName 文件名稱名* @param expires 過期策略* @return map*/public static Map<String, String> presignedGetObject(String objectName,Integer expires)throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, ServerException, InternalException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {PostPolicy policy = new PostPolicy(bucketName, ZonedDateTime.now().plusDays(7));// Add condition that 'key' (object name) equals to 'my-objectname'.policy.addEqualsCondition("key", objectName);// Add condition that 'Content-Type' starts with 'image/'.policy.addStartsWithCondition("Content-Type", "image/");// Add condition that 'content-length-range' is between 64kiB to 10MiB.policy.addContentLengthRangeCondition(64 * 1024, 10 * 1024 * 1024);return minioClient.getPresignedPostFormData(policy);}/*** 將URLDecoder編碼轉成UTF8** @param str* @return* @throws UnsupportedEncodingException*/public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");return URLDecoder.decode(url, "UTF-8");}}BeanConfig
import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan @Slf4j @Data public class MinIoConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.bucketName}")private String bucketName;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Value("${spring.profiles.active}")private String folder;@Beanpublic MinioUtils creatMinioClient() {return new MinioUtils(endpoint, bucketName, accessKey, secretKey, folder);}}總結
- 上一篇: android OnTouchListe
- 下一篇: 招聘小程序制作:连接人才与企业