安装
1、从官网下载minio二进制文件:
http://dl.minio.org.cn/server/minio/release/darwin-amd64/minio
2、新建minio安装目录,执行如下命令:
此处由百善109环境为参考:
mkdir -p /home/deploy/minIO/data
3、把二进制文件上传到安装目录后,执行:
chmod +x minio
export MINIO_ACCESS_KEY=minioadmin
export MINIO_SECRET_KEY=minioadmin
启动:./minio server /home/deploy/minIO/data
4、web端访问
http://10.1.9.109:9000/
账号密码为:minioadmin/minioadmin
相关api操作
1、maven
<dependencies>
<!-- minio依赖-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.3</version>
</dependency>
<!-- 官方 miniodemo需要的依赖-->
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.7.4</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
2、api操作
package com.wuxian.minio;
import io.minio.*;
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 okhttp3.*;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* 如下以10.1.9.109为例
*/
public class MinIODemo {
public static MinioClient minioClient;
@Before
public void init() {
// 初始化Minio客户端
minioClient = MinioClient.builder()
.endpoint("http://10.1.9.109:9000/")
.credentials("minioadmin", "minioadmin")
.build();
System.out.println(minioClient);
System.out.println();
}
// 1、验证桶是否存在
@Test
public void exists() throws Exception {
BucketExistsArgs btest2 = BucketExistsArgs.builder().bucket("1028").build();
boolean existFlag = minioClient.bucketExists(btest2);
System.out.println(existFlag);
}
//2、创建存储桶
@Test
public void create() throws Exception {
String bucketName = "java.minio.demo";
// 存储桶不存在则创建
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
System.out.printf("%s,创建成功", bucketName);
} else {
System.out.printf("%s,已存在", bucketName);
}
}
//3、查询所有桶的列表信息
@Test
public void selInfo() throws Exception {
List<Bucket> bucketList = minioClient.listBuckets();
bucketList.forEach(bucket ->
System.out.printf("存储桶名:%s,创建时间:%s ", bucket.name(), bucket.creationDate() + "\n"));
}
//4、删除存储桶
@Test
public void del() {
//注意:如果存储桶存在对象不为空时,删除会报错。
try {
String bucketName2 = "btest3";
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName2).build());
} catch (Exception e) {
e.printStackTrace();
}
}
//上传对象: PutObject方法(常用)
@Test
public void putObject() throws Exception {
String bucketName = "java.minio.demo";
// 创建InputStream上传
File file = new File("D:\\Image\\1eccd02d917ac2f33e0331f965e8f7de30ae84e4e0523a410f3e2e60fa50bf30.jpg");
InputStream inputStream = new FileInputStream(file);
long start = System.currentTimeMillis();
// 上传流
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object("2021/11/28/" + file.getName()).stream(inputStream, inputStream.available(), -1)
.build());
inputStream.close();
System.out.println("uploaded successfully 耗时:" + (System.currentTimeMillis() - start));
//添加的Object大小不能超过 5GB。
//默认情况下,如果已存在同名Object且对该Object有访问权限,则新添加的Object将覆盖原有的Object,并返回 200 OK。
//OSS没有文件夹的概念,所有资源都是以文件来存储,但您可以通过创建一个以正斜线(/)结尾,大小为 0的Object来创建模拟文件夹(指定 /后,默认会自动创建)。
}
//上传对象: uploadObject方法
@Test
public void uploadObject() throws Exception {
String bucketName = "java.minio.demo";
long start = System.currentTimeMillis();
// 上传文件
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
.filename("D:\\Image\\1eccd02d917ac2f33e0331f965e8f7de30ae84e4e0523a410f3e2e60fa50bf30.jpg")
.build());
System.out.println("uploaded successfully 耗时:" + (System.currentTimeMillis() - start));
}
//获取对象: getObject方法
@Test
public void getObject() throws Exception {
String bucketName = "java.minio.demo";
// GetObjectResponse 继承了 InputStream类
GetObjectResponse objectResponse = minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
.build());
System.out.println(objectResponse.bucket());
System.out.println(objectResponse.object());
int available = objectResponse.read();
System.out.println(available);
// Close the input stream.
objectResponse.close();
}
//获取对象: downloadObject方法
@Test
public void downloadObject() throws Exception {
String bucketName = "java.minio.demo";
minioClient.downloadObject(DownloadObjectArgs.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
.filename("D:\\Test\\666.jpg") // 必须指定文件名
.build());
}
//获取对象: getPresignedObjectUrl方法
@Test
public void getPresignedObjectUrl() throws Exception {
String bucketName = "java.minio.demo";
String objectUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
.method(Method.GET)
//.expiry(60) // 单位秒
.expiry(30, TimeUnit.SECONDS)
.build());
//返回获取文件对象的URL GET请求,此 URL过期时间为一分钟。
System.out.println(objectUrl);
}
//获取对象: getPresignedPostFormData方法
/**
* 使用此方法,获取对象的上传策略(包含签名、文件信息、路径等),然后使用这些信息采用 POST 方法的表单数据上传数据。也就是可以生成一个临时上传的信息对象,第三方可以使用这些信息,就可以上传文件。
*
* 注意:
*
* 第三方请求中的签名必须和 创建策略中的签名参数等一致,不符合策略要求的就会上传失败。
* 一般使用场景:
*
* 第三方请求应用服务器接口,来获取一个上传策略信息。
* 第三方使用 Http+访问策略信息直接请求应用服务器接口进行上传文件。
*/
@Test
public void getPresignedPostFormData() throws Exception {
String bucketName = "java.minio.demo";
String objectName = "2021/11/28/100元3.jpg";
// 1. 创建一个Post 策略
// 为存储桶创建一个上传策略,过期时间为7天
PostPolicy policy = new PostPolicy(bucketName, ZonedDateTime.now().plusDays(7));
// 设置一个参数key-value,值为上传对象的名称(保存在桶中的名字)
policy.addEqualsCondition("key", objectName);
// 添加 Content-Type以"image/"开头,表示只能上传照片
policy.addStartsWithCondition("Content-Type", "image/");
// 设置上传文件的大小 10kiB to 10MiB.
policy.addContentLengthRangeCondition(10 * 1024, 10 * 1024 * 1024);
// 2. 获取策略的 认证令牌、签名等信息
Map<String, String> formData = minioClient.getPresignedPostFormData(policy);
// 3.模拟第三方,使用 OkHttp调用 Post上传对象
// 创建 MultipartBody对象
MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
multipartBuilder.setType(MultipartBody.FORM);
for (Map.Entry<String, String> entry : formData.entrySet()) {
multipartBuilder.addFormDataPart(entry.getKey(), entry.getValue());
}
multipartBuilder.addFormDataPart("key", objectName);// 必须要和策略参数一样
multipartBuilder.addFormDataPart("Content-Type", "image/png");
File uploadFile = new File("D:\\Image\\1eccd02d917ac2f33e0331f965e8f7de30ae84e4e0523a410f3e2e60fa50bf30.jpg");
// 上传文件的 fileName自定义,这里方便就用 objectName
multipartBuilder.addFormDataPart(
"file", objectName, RequestBody.create(uploadFile, null));
// 使用OkHttp调用Post上传对象
Request request =
new Request.Builder()
.url("http://10.1.9.109:9000/" + bucketName)
.post(multipartBuilder.build())
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
if (response.isSuccessful()) {
System.out.println("uploaded successfully using POST object");
} else {
System.out.println("Failed to upload Pictures");
}
}
//复制对象: copyObject方法
@Test
public void copyObject() throws Exception {
String bucketName = "java.minio.demo";
String bucketName2 = "btest2";
// 将 bucketName中的100元2.jpg文件,复制到bucketName2桶下
minioClient.copyObject(CopyObjectArgs.builder()
.source(CopySource.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
.build())
.bucket(bucketName2)
.object("2021/11/28/100元copy.jpg")
.build());
}
//删除对象: removeObject方法
@Test
public void removeObject() throws Exception {
String bucketName = "java.minio.demo";
minioClient.removeObject(RemoveObjectArgs.builder()
.bucket(bucketName)
.object("2021/11/28/100元2.jpg")
//.versionId("my-versionid") //还可以删除指定版本号的对象
.build());
}
//删除对象: removeObjects方法
@Test
public void removeObjects() throws Exception {
String bucketName = "java.minio.demo";
// 构建需要删除的对象
List<DeleteObject> objects = new LinkedList<>();
objects.add(new DeleteObject("2021/11/28/100元.jpg"));
objects.add(new DeleteObject("2021/11/28/100元2.jpg"));
objects.add(new DeleteObject("2021/11/28/100元3.jpg"));
// 删除
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder()
.bucket(bucketName)
.objects(objects)
.build());
for (Result<DeleteError> result : results) {
// 删除文件不存在时,不会报错
DeleteError error = result.get();
System.out.println("Error in deleting object " + error.objectName() + "; " + error.message());
}
}
//桶的对象信息查询: 查询桶下对象
@Test
public void selBucket() throws Exception {
String bucketName2 = "java.minio.demo";
Iterable<Result<Item>> listObjects = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName2)
.build());
for (Result<Item> result : listObjects) {
Item item = result.get();
System.out.println(item.objectName() + " " + item.size() );
}
}
//桶的对象信息查询: 递归查询桶下对象
@Test
public void selBucket2() throws Exception {
String bucketName2 = "java.minio.demo";
Iterable<Result<Item>> listObjects = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName2)
.recursive(true)
.build());
for (Result<Item> result : listObjects) {
Item item = result.get();
System.out.println(item.objectName() + " " + item.size() );
}
}
//桶的对象信息查询: 条件查询
@Test
public void selBucket3() throws Exception {
String bucketName2 = "java.minio.demo";
// 条件查询
Iterable<Result<Item>> listObjects = minioClient.listObjects(ListObjectsArgs.builder()
.bucket(bucketName2)
.startAfter("2021")
.prefix("2") // 指定前缀
.maxKeys(100) // 最大数量
.recursive(true) // 递归
.build());
for (Result<Item> result : listObjects) {
Item item = result.get();
System.out.println(item.objectName() + " " + item.size() );
}
}
}