Java之MinIO存储桶和对象API使用

MinIO Java Client SDK提供简单的API来访问任何与Amazon S3兼容的对象存储服务。

官方demo: https://github.com/minio/minio-java
官方文档:https://docs.min.io/docs/java-client-api-reference.html
新版 MinIO和旧版在 API使用上还是有一定的区别,比如:新版 MinIO采用 Builder构建者模式来构造 MinioClient对象。所以,官方demo仅供参考,尽量查看英文官方文档。

在这里插入图片描述

 

一、环境搭建

1、创建一个 maven项目,引入依赖:

    <!-- 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>

这里我把 官方demo 放到了我的项目中,所以必须引入 progressbar依赖。否则忽略它。

2、初始化Minio客户端
注意:

  • 新版 MinIO 采用 Builder构建者模式来构造 MinioClient对象。
  • API端口和 访问控制台端口不要搞混了。
  •         // 初始化Minio客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint("http://xxx.xxx.xxx.xxx:9000/")
                    .credentials("admin", "xxx")
                    .build();
            System.out.println(minioClient);
    

    获取到 MinioClient对象,就可以进行 MinIO的 API操作使用了。

    二、存储桶基本使用

    1、检查存储桶是否存在。

  • boolean bucketExists(BucketExistsArgs args):检查存储桶是否存在。
  • 示例:

  • BucketExistsArgs btest2 = BucketExistsArgs.builder().bucket("btest2").build();
    boolean existFlag = minioClient.bucketExists(btest2);
    

    注意: 旧版参数是字符串 - 存储桶名,新版需要 build来构造 BucketExistsArgs对象。

    2、创建存储桶
    public void makeBucket(MakeBucketArgs args):创建一个启用给定区域和对象锁定功能的存储桶。
    示例1:存储桶不存在则创建

  • 		String bucketName = "java.minio.demo";
    		// 存储桶不存在则创建
    		if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
    			minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
    			System.out.printf("%s,创建成功\n", bucketName);
    		}else{
    			System.out.printf("%s,已存在\n", bucketName);
    		}
    

    3、查询存储桶

    3.1 查询所有桶的列表信息

  • public List listBuckets():列出所有桶的桶信息。
  • 示例:

  •         List<Bucket> bucketList = minioClient.listBuckets();
            bucketList.forEach(bucket -> {
                System.out.printf("存储桶名:%s,创建时间:%s \n", bucket.name(), bucket.creationDate());
            });
    

    在这里插入图片描述

    注意:桶的创建时间默认是美国时间,创建桶时我们可以指定桶的时区或者设置 MinIO服务器时区。

    4、删除存储桶

  • public void removeBucket(RemoveBucketArgs args):删除一个空桶。
  • 示例:

  • String bucketName2 = "btest3";       minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName2).build());
    

     

    注意:如果存储桶存在对象不为空时,删除会报错。

    二、对象基本使用
    1、上传对象
    1.1 PutObject方法
    public ObjectWriteResponse putObject(PutObjectArgs args):将给定的流上传为存储桶中的对象。
    示例1,InputStream上传:

  •         String bucketName = "java.minio.demo";
            // 创建InputStream上传
            File file = new File("D:\\DownUpLoadTempFiles\\100元.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来创建模拟文件夹(指定 /后,默认会自动创建)。
    上传文件是也可以使用SSE-C加密,添加自定义元数据及消息头等操作。

    1.2 uploadObject方法
    public void uploadObject(UploadObjectArgs args):将文件中的内容作为存储桶中的对象上传。
    不太常用,一般适合上传磁盘文件(mc cp命令更方便)。
    示例:

  •         String bucketName = "java.minio.demo";
            
            long start = System.currentTimeMillis();
            // 上传文件
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket(bucketName)
                            .object("2021/11/28/100元2.jpg")
                            .filename("D:\\DownUpLoadTempFiles\\100元.jpg")
                            .build());
            System.out.println("uploaded successfully 耗时:" + (System.currentTimeMillis() - start));
    

     

    2、获取对象

    2.1 getObject方法

  • public GetObjectResponse getObject(GetObjectArgs args):获取对象的数据。
  • 示例:

  • 		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());
    		byte[] allBytes = objectResponse.readAllBytes();
    		System.out.println(allBytes);
    		
    		// Close the input stream.
    		objectResponse.close();
    

    注意:

    返回结果是 GetObjectResponse类,它继承了 InputStream类。
    GetObjectResponse使用后返回必须关闭以释放网络资源。
    此操作需要对此Object具有读权限。
    2.2 downloadObject方法
    public void downloadObject(DownloadObjectArgs args):将对象的数据下载到磁盘。

  •         String bucketName = "java.minio.demo";
    
            minioClient.downloadObject(DownloadObjectArgs.builder()
                    .bucket(bucketName)
                    .object("2021/11/28/100元2.jpg")
                    .filename("D:\\TempFiles\\100元2.jpg") // 必须指定文件名
                    .build());
    

    2.3 getPresignedObjectUrl方法
    public String getPresignedObjectUrl(GetPresignedObjectUrlArgs args):获取 HTTP 方法、到期时间和自定义请求参数的对象的预签名 URL。
    示例:返回获取文件对象的URL GET请求,此 URL过期时间为一分钟。

  •         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());
            System.out.println(objectUrl);
    

    返回带签名的URL有点小长,过期之后访问会报错。
    在这里插入图片描述

    使用此方法,可以提供给不用登录进行图片浏览,第三方共享访问等。
    我们还可以对返回 URL,根据业务做一些参数验签等控制。

  • 2.4 getPresignedPostFormData方法

  • public Map<String,String> getPresignedPostFormData(PostPolicy policy):获取对象的PostPolicy的表单数据以使用 POST 方法上传其数据。
  •  

           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:\\DownUpLoadTempFiles\\100元.jpg");
            // 上传文件的 fileName自定义,这里方便就用 objectName
            multipartBuilder.addFormDataPart(
                    "file", objectName, RequestBody.create(uploadFile, null));
            // 使用OkHttp调用Post上传对象
            Request request =
                    new Request.Builder()
                            .url("http://192.168.198.110: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");
            }
    

    使用此方法,获取对象的上传策略(包含签名、文件信息、路径等),然后使用这些信息采用 POST 方法的表单数据上传数据。也就是可以生成一个临时上传的信息对象,第三方可以使用这些信息,就可以上传文件。

    注意:

    第三方请求中的签名必须和 创建策略中的签名参数等一致,不符合策略要求的就会上传失败。
    一般使用场景:

    第三方请求应用服务器接口,来获取一个上传策略信息。
    第三方使用 Http+访问策略信息直接请求应用服务器接口进行上传文件。
    3、复制对象
    3.1 copyObject方法
    public ObjectWriteResponse copyObject(CopyObjectArgs args):通过服务器端从另一个对象复制数据来创建一个对象。
    示例:

  •         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());
    

    mc cp命令更方便。

    4、删除对象

    4.1 removeObject方法

  • public void removeObject(RemoveObjectArgs args) :移除一个对象。
  • 示例:

  •        String bucketName = "java.minio.demo";
    
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object("2021/11/28/100元2.jpg")
                    //.versionId("my-versionid") //还可以删除指定版本号的对象
                    .build());
    

    4.2 removeObjects方法

  • public Iterable<Result> removeObjects(RemoveObjectsArgs args):懒惰地删除多个对象。它需要迭代返回的 Iterable 以执行删除。
  • 示例:

  •         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());
            }
    

    5、桶的对象信息查询

  • public Iterable<Result> listObjects(ListObjectsArgs args):列出桶的对象信息。
  • 5.1 查询桶下对象

  •         String bucketName2 = "btest2";
    
            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() + "\t" + item.size() );
            }
    

    在这里插入图片描述

    5.2 递归查询桶下对象

  •         String bucketName2 = "btest2";
    
            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() + "\t" + item.size() );
            }
    

     在这里插入图片描述

    5.3 条件查询

            // 条件查询
            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() + "\t" + item.size() );
            }
    

     在这里插入图片描述

    更多使用请查看官方文档。


    版权声明:本文为CSDN博主「Charge8」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_42402854/article/details/121592546

     

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值