MinIO 官方:min.io/
中文版:www.minio.org.cn/ 更新不及时,有坑
环境搭建:
单机部署:基于docker
docker pull minio/minio
//创建文件夹
mkdir -p /data/minio/config
mkdir -p /data/minio/data
#启动
docker run -p 9000:9000 -p 9001:9001 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=admin12345" -v /data/minio/data:/data -v /data/minio/config:/root/.minio minio/minio server /data --console-address ":9001"
后端代码
javaClient
上传
try {
//1.连接Minio客户端
MinioClient minioClient = MinioClient.builder().endpoint("http://139.196.90.55:9000")
.credentials("admin", "admin12345")
.build();
//2.bucket桶是否存在,确定上传的位置
String bucketName = "image-test01";
boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
//不存在创建
if (!b){
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
//3.上传
minioClient.uploadObject(UploadObjectArgs.builder()
.bucket(bucketName)
.object("2.jpg")
.filename("C:\\Users\\wen\\Pictures\\2.jpg")
.build());
System.out.println("上传成功");
} catch (ErrorResponseException e) {
e.printStackTrace();
System.out.println("上传失败");
}
下载
//1.连接Minio客户端
MinioClient minioClient = MinioClient.builder().endpoint("http://139.196.90.55:9000")
.credentials("admin", "admin12345")
.build();
try {
//下载
minioClient.downloadObject(DownloadObjectArgs.builder()
.bucket("image-test01")
.object("1.jpg")
.filename("1.jpg")
.build());
} catch (Exception e) {
e.printStackTrace();
}
springboot整合MInio
依赖
<!--minio依赖-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.0</version>
</dependency>
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.5.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
yml配置
minio:
url: http://139.196.90.55:9000 #新版minio有两个端口注意 9000给客户端使用,9001登录服务端使用
username: admin
password: 密码
bucketName: test
配置文件
@Configuration
public class MinioClientConfig {
@Value("${minio.url}")
private String url;
@Value("${minio.username}")
private String userName;
@Value("${minio.password}")
private String password;
@Bean
public MinioClient minioClient(){
MinioClient minioClient = MinioClient.builder().endpoint(url).credentials(userName, password).build();
return minioClient;
}
}
常用API utli
package com.wen.util;
/**
* minio常用操作
*/
public class MinioUtil {
@Autowired
private MinioClient minioClient;
@Value("${minio.bucketName}")
private String bucketName;
//文件上传
public boolean upload(MultipartFile file){
//返回客户端文件系统中的原始文件名
String originalFilename = file.getOriginalFilename();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(originalFilename)
.stream(inputStream, file.getSize(), -1)
.build());
return ResultMessage.TRUE;
} catch (Exception e) {
e.printStackTrace();
}finally {
if (inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ResultMessage.FALSE;
}
//文件下载
public void download(HttpServletResponse response,String fileName){
InputStream inputStream = null;
try {
//获取文件源信息
StatObjectResponse statObject = minioClient.statObject(StatObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build());
//设置响应的内容类型 --浏览器对应不同类型做不同处理
response.setContentType(statObject.contentType());
//设置响应头
response.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(fileName, "UTF-8"));
//文件下载
inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName)
.object(fileName).build());
//利用apache的IOUtils
IOUtils.copy(inputStream, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//文件删除
public boolean delete(String fileName){
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName)
.object(fileName).build());
return ResultMessage.TRUE;
} catch (Exception e) {
e.printStackTrace();
}
return ResultMessage.FALSE;
}
//桶是否存在
public boolean bucketExists(){
boolean b = false;
try {
b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (b){
return ResultMessage.TRUE;
}
} catch (Exception e) {
e.printStackTrace();
}
return ResultMessage.FALSE;
}
//创建桶
public boolean createBucket(){
try {
boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (!b){
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
return ResultMessage.TRUE;
} catch (Exception e) {
e.printStackTrace();
}
return ResultMessage.FALSE;
}
//获取桶列表
public List getBucketList() throws Exception {
List<Bucket> buckets = minioClient.listBuckets();
List list = new ArrayList();
for (Bucket bucket : buckets) {
String name = bucket.name();
list.add(name);
}
return list;
}
//获取指定bucketName下所有文件
public List<Object> getFolderList(String bucketName) throws Exception{
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
Iterator<Result<Item>> iterator = results.iterator();
List<Object> items = new ArrayList<>();
String format = "{'fileName':'%s','fileSize':'%s'}";
while(iterator.hasNext()) {
Item item = iterator.next().get();
items.add(JSON.parse((String.format(format, item.objectName(),
formatFileSize(item.size())))));
}
return items;
}
/**
* 将块文件合并到新桶 块文件必须满足 名字是 0 1 2 3 5(方便排序).. 合并文件前排列一下块文件的顺序(升序) 怎么切的顺序就怎么合的顺序
* @param bucketName 存块文件的桶
* @param bucketName1 存新文件的桶
* @param fileName1 存到新桶中的文件名称
* @return
*/
public boolean merge(String bucketName,String bucketName1,String fileName1) {
try{
List<ComposeSource> sourceObjectList = new ArrayList<ComposeSource>();
List<Object> folderList = this.getFolderList(bucketName);
List<String> fileNames = new ArrayList<>();
if (folderList != null && !folderList.isEmpty()){
for (int i = 0; i < folderList.size(); i++) {
Map o = (Map)folderList.get(i);
String name = (String) o.get("fileName");
fileNames.add(name);
}
}
if (!fileNames.isEmpty()){
Collections.sort(fileNames, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (Integer.parseInt(o2) > Integer.parseInt(o1)){
return -1;
}
return 1;
}
});
for (String name : fileNames) {
sourceObjectList.add(ComposeSource.builder().bucket(bucketName).object(name).build());
}
}
minioClient.composeObject(
ComposeObjectArgs.builder()
.bucket(bucketName1)
.object(fileName1)
.sources(sourceObjectList)
.build());
return ResultMessage.TRUE;
}catch (Exception e){
e.printStackTrace();
}
return ResultMessage.FALSE;
}
private static String formatFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
String wrongSize = "0B";
if (fileS == 0) {
return wrongSize;
}
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + " B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + " KB";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + " MB";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + " GB";
}
return fileSizeString;
}}