MinIo对象存储文件上传,下载,预览,批量上传,创建桶等
MinIo 操作工具类
MinIo 官网地址 https://min.io/
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); } }
pom 文件引入依赖
<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>
注意事项:MinIo sdk是最新,和旧版一些方法有差异,请求是异步的
开启永久访问策略
- 控制台界面找到你要永久开放的桶
- 点击“manage”
- 在点击访问规则
- 设置访问规则“prefix” * 权限只读就可以了
- 资源访问路径 http://xxx.xxx.xxx:9000/桶/文件名
哇!又赚了一天人民币