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/桶/文件名



MinIo对象存储文件上传,下载,预览,批量上传,创建桶等的更多相关文章
- Spring Boot2(十四):单文件上传/下载,文件批量上传
文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...
- Struts2实现文件上传下载功能(批量上传)
今天来发布一个使用Struts2上传下载的项目, struts2为文件上传下载提供了好的实现机制, 首先,可以先看一下我的项目截图 关于需要使用的jar包,需要用到commons-fileupload ...
- servlet实现文件上传,预览,下载和删除
一.准备工作 1.1 文件上传插件:uploadify: 1.2 文件上传所需jar包:commons-fileupload-1.3.1.jar和commons-io-2.2.jar 1.3 将数 ...
- JS兼容各个浏览器的本地图片上传即时预览效果
JS兼容各个浏览器的本地图片上传即时预览效果 很早以前 在工作曾经碰到这么一个需求,当时也是纠结了很久,也是google了很久,没有碰到合适的demo,今天特意研究了下这方面的的问题,所以也就做了个简 ...
- 基于html5的多图片上传,预览
基于html5的多图片上传 本文是建立在张鑫旭大神的多文图片传的基础之上. 首先先放出来大神多图片上传的博客地址:http://www.zhangxinxu.com/wordpress/2011/09 ...
- html之file标签 --- 图片上传前预览 -- FileReader
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
- 基于“formData批量上传的多种实现” 的多图片预览、上传的多种实现
前言 图片上传是web项目常见的需求,我基于之前的博客的代码(请戳:formData批量上传的多种实现)里的第三种方法实现多图片的预览.上传,并且支持三种方式添加图片到上传列表:选择图片.复制粘贴图片 ...
- file标签 - 图片上传前预览 - FileReader & 网络图片转base64和文件流
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
- 原生js实现图片预览并上传
最近主导的PC客户端网站重构工程告一段落,下一阶段开始给公司APP开发H5页面,技术栈是react.最近碰到一个需求:需要在H5页面上添加身份证照片,预览并上传.因为要兼容安卓4.4以下版本的手机,所 ...
- 【转】html之file标签 --- 图片上传前预览 -- FileReader
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
随机推荐
- OpenHarmony社区运营报告(2023年5月)
本月快讯 ● 2023年6月11-13日,2023开放原子全球开源峰会即将在北京北人亦创国际会展中心盛大开幕.2023开放原子全球开源峰会上,OpenAtom OpenHarmony(以下简称&q ...
- OpenHarmony社区运营报告(2023年2月)
本月快讯 • 2023年2月25日,以"技术构筑万物智联"为主题的第一届开放原子开源基金会OpenAtom OpenHarmony(以下简称"OpenHarmony& ...
- 成长计划知识赋能 | 第九期:渐进式深入理解OpenHarmony系统
成长计划知识赋能直播第九期如约而至,面向OpenHarmony初中级开发者,解析OpenHarmony系统架构和驱动框架,助力开发者快速上手OpenHarmony系统开发. 详情见海报内容,资深软 ...
- 将Map中对应的key和value赋值到对象中
BeanUtils位于import org.apache.commons.beanutils.BeanUtils包下 其使用方法: Map<String, Object> objectMa ...
- RabbitMQ 06 工作队列模式
工作队列模式结构图: 这种模式非常适合多个工人等待任务到来的场景.任务有多个,一个一个丢进消息队列,工人也有很多个,就可以将这些任务分配个各个工人,让他们各自负责一些任务,并且做的快的工人还可以多完成 ...
- HarmonyOS:Neural Network Runtime对接AI推理框架开发指导
场景介绍 Neural Network Runtime作为AI推理引擎和加速芯片的桥梁,为AI推理引擎提供精简的Native接口,满足推理引擎通过加速芯片执行端到端推理的需求. 本文以图1展示的A ...
- 正则表达针对html(九)
前言 关于处理一些html的东西. 正文 假设有一段html文本: <?xml version="1.0" encoding="UTF-8"?> & ...
- CC1TransformedMap链学习
跟着看了白日梦组长的视频,记录一下调试学习过程 CC1链学习 TransformedMap链 ObjectInputStream.readObject() AnnotationInvocationHa ...
- 《c#高级编程》第4章C#4.0中的更改(八)——协变和逆变
一.协变 C#协变是指在一些特定的情况下,可以将一个派生类型的实例赋值给其基类或接口类型的引用.这里的"派生类型"指的是从某个基类或接口继承并增加了新的成员的类型. C# 4.0 ...
- 力扣153(java&python)-寻找旋转排序数组中的最小值(中等)
题目: 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:若旋转 4 次,则可以 ...