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"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
随机推荐
- Discovery直播 | 移动应用“通行证”——钥匙环,解锁管家式安全出行服务
用户在登录环节的直接诉求是:别让我等.别让我想.别让我烦.而帐号输入.繁琐验证,以及由此带来的安全风险,总会让很多人望而却步. 如何在简化登录流程的同时保障登录凭证安全?如何帮助用户一键免密登录同一开 ...
- 设置 BCompare 打开文件时的默认字符编码
每次比对 .h .cpp 文件,BCompare总是默认以西欧字符编码打开文件,导致中文都变成乱码了,还需要手动的修改文件字符编码,这样才能正常的显示.非常的不方便 然后我们就需要设置默认的字符编码, ...
- mysql迁移sqlServer和mybatisPlus下查询语句转换为SqlServer2008
mysql数据迁移sqlServer2008 mybatisPlus下查询语句转换 一.mysql数据迁移到sqlServer2008中(包括数据结构和数据) 最近公司项目需要使用sqlServer以 ...
- Mybatis终极案例之注解开发
Mybatis终极案例之注解开发 一.注解开发实现CURD操作 1.环境搭建 参考入门案例,环境搭建主要分为如下几步: 1.配置pom.xml <packaging>jar</pac ...
- BI 和报表有什么区别
BI 从早期提出的概念上来划分可以分为数据仓库.ETL.olap 和报表这几部分可以看到报表只是 BI 中的一个组成部分,只不过数据在 web 端展示时通常是通过报表形式,所以经常会把报表当做是 BI ...
- nginx重新整理——————http 模块中的请求过程[十一]
前言 简单介绍一下http的一些指令. 正文 一般http的嵌套规则是这样的: http{ upstream{} split_clients {} map{} gep{} server{ if(){} ...
- signalr 应用于微信小程序(一)
前言 在2017年基于signalr 和微信小程序 写的脚本. 正文 先安装signalr: 1.安装singalr,用nutget就行,用这个包管理就行. 2.使用singalr 3.根据singa ...
- JavaScript中数值小知识
1. 数值10.0 这种类似的会被去掉数值后的0 之所以这样是因为,整数的存储空间占用比浮点数小,当一个数值不是真浮点数(即10.0这种格式),会被转换为整数10,如果业务中有一些需求需要进行数值位数 ...
- OceanBase初体验之Docker快速部署试用环境
前置条件 准备好一台安装了 Docker 的 Linux 服务器,确保能够连接到 Docker Hub 仓库. 执行以下命令拉取最新的 OceanBase 镜像: docker pull oceanb ...
- 延迟绑定与retdlresolve
延迟绑定与retdlresolve 我们以前在ret2libc的时候,我们泄露的libc地址是通过延迟绑定实现的,我们知道,在调用libc里面的函数时候,它会先通过plt表和gor表绑定到,函数真实地 ...