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"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
随机推荐
- Spring Boot 嵌入式服务器、Hibernate 关系和 Spring Data 全解析
嵌入式服务器 Spring Boot 的嵌入式服务器功能是一项方便而强大的功能,它允许你在应用程序中直接运行 Web 服务器,无需将其部署到单独的独立 Web 服务器中.这使得开发.测试和部署 Web ...
- 使用GUI--tkinter 制作一个批量修改文件名的桌面软件
''' title:批量修改文件名称 author:huyang createtime:2021-01-29 14:50:00 ''' from tkinter import * from tkint ...
- mybatis plugin源码解析
概述 Plugin,意为插件,是mybatis为开发者提供的,对方法进行自定义编程的手段.其中用到了动态代理.反射方法,通过指定需要增强的对象与方法,进行程序编写. 核心类 主要涉及几个核心类:Int ...
- 学习Source Generators之打包成Nuget使用
前面我们简单的实现了一个从swagger生成实体类的Generator,在实际使用中,通过nuget包引用使用会更方便,那么本篇文章将介绍如何将Generator打包成Nuget来使用. 打包Nuge ...
- C++ 引用和指针:内存地址、创建方法及应用解析
C++ 引用和指针 创建引用 引用变量是对现有变量的"别名",它是使用 & 运算符创建的: string food = "Pizza"; // 食物变量 ...
- 重新点亮shell————awk函数[十五]
前言 简单介绍一下awk函数. 正文 算术函数 字符串函数 自定义函数 例子: 结 awk就到这里了.
- c# seo 百度sitemap书写
前言 我们知道对页面百度收录,有两种方式: 1.百度自己抓取. 2.自己提交sitemap让百度来抓取. sitemap 一般的一个业务逻辑是: 生成sitemap xml,然后每隔一段时间更新即可, ...
- Flutter笔记 - 事件分发
事件处理流程 Flutter 事件处理流程主要分两步,为了聚焦核心流程,我们以用户触摸事件为例来说明: 命中测试:当手指按下时,触发 PointerDownEvent 事件,按照深度优先遍历当前渲染( ...
- tomcat 服务版本内存设置
1. 安装服务,如需指定java路径,需要在service.bat 中修改, 如下图 其中 pa代表当前目录 2. 安装服务, service.bat install 服务名,如下图示例 3. 内存设 ...
- 使用树莓派远程控制灯继电器开关,dht11温湿度网页显示,树莓派物联网
前段时间使用esp8266搞了个智能家居,通过网页控制,但是没有办法实现远程控制,只能局域网控制,因为我没有平台,使用机制云等平台还需要开发app 使用chatgpt生成的main.py程序 from ...