[Megrez Boot] starter-minio

MinIO是一款开源的对象存储服务器。本项目基于Spring Boot自动配置MinioClient,开发MinIO客户端程序更方便。

项目源码:Gitee

简介

megrez.boot.autoconfigure.minio.MinioProperties属性配置

@Data
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

    
    /** 服务器参数 */
    private Server server = new Server();
    /** 连接参数 */
    private Connection connection = new Connection();
    /** 连接参数 */
    private Proxy proxy = new Proxy();

    @Data
    public static class Proxy {
        private String host;
        private Integer port;
    }

    @Data
    public static class Connection {
        /**
         * Define the connect timeout for the Minio Client.
         */
        private Duration connectTimeout = Duration.ofSeconds(10);

        /**
         * Define the write timeout for the Minio Client.
         */
        private Duration writeTimeout = Duration.ofSeconds(60);

        /**
         * Define the read timeout for the Minio Client.
         */
        private Duration readTimeout = Duration.ofSeconds(10);
    }

    @Data
    public static class Server {

        /**
         * URL for Minio instance. Can include the HTTP scheme. Must include the port.
         * If the port is not provided, then the port of the HTTP is taken.
         */
        private String endpoint = "127.0.0.1";

        private Integer port = 9000;

        /**
         * Access key (login) on Minio instance
         */
        private String accessKey = "admin";

        /**
         * Secret key (password) on Minio instance
         */
        private String secretKey = "admin";

        /**
         * If the scheme is not provided in {@code url} property, define if the
         * connection is done via HTTP or HTTPS.
         */
        private boolean secure = false;
    }

}

megrez.boot.autoconfigure.minio.MinioAutoConfiguration自动配置

@Slf4j
@Configuration
@ConditionalOnClass(MinioClient.class)
@EnableConfigurationProperties(MinioProperties.class)
public class MinioAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MinioClient minioClient(MinioProperties properties, ObjectProvider<MinioConfigurer> configurers) {

        final Server server = properties.getServer();
        final Connection connection = properties.getConnection();
        final Proxy proxy = properties.getProxy();

        log.info("Initializing MinioClient [{}:{}]", server.getEndpoint(), server.getPort());

        final MinioClient.Builder builder = MinioClient.builder()
                .endpoint(server.getEndpoint(), server.getPort(), server.isSecure())
                .credentials(server.getAccessKey(), server.getSecretKey());

        if (StringUtils.hasText(proxy.getHost())) {
            log.info("Http proxy enabled [{}:{}]}", proxy.getHost(), proxy.getPort());
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP,
                            new InetSocketAddress(proxy.getHost(), proxy.getPort())))
                    .build();
            builder.httpClient(okHttpClient);
        }

        // 自定义配置处理
        configurers.forEach(configurer -> configurer.configure(builder));

        MinioClient minioClient = builder.build();
        minioClient.setTimeout(
                connection.getConnectTimeout().toMillis(),
                connection.getWriteTimeout().toMillis(),
                connection.getReadTimeout().toMillis());
        return minioClient;
    }

    @Bean
    @ConditionalOnMissingBean
    public MinioObjectClient minioObjectClient(MinioClient minioClient) {
        return new MinioObjectClient(minioClient);
    }

    @Bean
    @ConditionalOnMissingBean
    public MinioBucketClient minioBucketClient(MinioClient minioClient) {
        return new MinioBucketClient(minioClient);
    }
}

megrez.boot.autoconfigure.minio.MinioObjectClient对象操作服务


@RequiredArgsConstructor
public class MinioObjectClient {
    private final MinioClient client;

    /**
     * 上传对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param stream     流
     * @param consumer   builder消费
     * @return
     */
    public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream stream,
            Consumer<PutObjectArgs.Builder> consumer) {
        try {
            PutObjectArgs.Builder builder = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(stream, stream.available(), -1);

            if (consumer != null) {
                consumer.accept(builder);
            }

            return client.putObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 上传对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param stream     流
     * @return
     */
    public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream stream) {
        return putObject(bucketName, objectName, stream, null);
    }

    /**
     * 获取对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName, Consumer<GetObjectArgs.Builder> consumer) {
        try {
            GetObjectArgs.Builder builder = GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);

            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName) {
        return getObject(bucketName, objectName, null);
    }

    /**
     * 获取对象流-支持端点续传
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param offset     起始字节的位置
     * @param length     要读取的长度 (可选,如果无值则代表读到对象结尾)
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName, Long offset, Long length) {
        return getObject(bucketName, objectName, builder -> {
            builder.offset(offset);
            if (length != null) {
                builder.length(length);
            }
        });
    }

    /**
     * 获取对象信息和对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public StatObjectResponse statObject(String bucketName, String objectName,
            Consumer<StatObjectArgs.Builder> consumer) {
        try {
            StatObjectArgs.Builder builder = StatObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);

            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.statObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象信息和对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public StatObjectResponse statObject(String bucketName, String objectName) {
        return statObject(bucketName, objectName, null);
    }

    /**
     * 对象是否存在
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public boolean existObject(String bucketName, String objectName) {
        try {
            StatObjectResponse response = statObject(bucketName, objectName, null);
            return response != null;
        } catch (MinioRuntimeException e) {
            return false;
        }
    }

    /**
     * 获取对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public Map<String, String> getObjectUserMetadata(String bucketName, String objectName) {
        return statObject(bucketName, objectName).userMetadata();
    }

    /**
     * 获取预签名对象网址, 默认Method.GET方法,分享链接地址失效时间为7天
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   bilder消费
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String objectName,
            Consumer<GetPresignedObjectUrlArgs.Builder> consumer) {
        try {
            GetPresignedObjectUrlArgs.Builder builder = GetPresignedObjectUrlArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .method(Method.GET);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getPresignedObjectUrl(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param method     方法, GET, HEAD, POST, PUT, DELETE;
     * @param expiry     失效时间(以秒为单位),默认是7天,不得大于七天
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String objectName, Method method, Duration expiry) {
        return getPresignedObjectUrl(bucketName, objectName, builder -> {
            builder.method(method);
            if (expiry != null) {
                builder.expiry((int) expiry.toSeconds());
            }
        });
    }

    /**
     * 根据对象前缀查询对象
     * 
     * @param bucketName 桶
     * @param consumer   builder消费
     * @return
     */
    public List<Item> listObjects(String bucketName, Consumer<ListObjectsArgs.Builder> consumer) {
        try {
            ListObjectsArgs.Builder builder = ListObjectsArgs.builder()
                    .bucket(bucketName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            Iterable<Result<Item>> iterable = client.listObjects(builder.build());
            return StreamSupport
                    .stream(iterable.spliterator(), true)
                    .map(itemResult -> {
                        try {
                            return itemResult.get();
                        } catch (InvalidKeyException | ErrorResponseException | IllegalArgumentException
                                | InsufficientDataException | InternalException | InvalidResponseException
                                | NoSuchAlgorithmException | ServerException | XmlParserException | IOException e) {
                            throw new MinioRuntimeException(e);
                        }
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 根据对象前缀查询对象
     * 
     * @param bucketName 桶
     * @param prefix     桶中对象的前缀 默认 空字符串
     * @param recursive  是否递归子目录
     * @return
     */
    public List<Item> listObjects(String bucketName, String prefix, Boolean recursive) {
        return listObjects(bucketName, builder -> {
            if (StringUtils.hasText(prefix)) {
                builder.prefix(prefix);
            }
            if (recursive != null) {
                builder.recursive(recursive);
            }
        });
    }

    /**
     * 组合源对象列表, 通过使用服务器端副本组合来自不同源对象的数据来创建对象,服务器上已存在的对象列表再次组合成一个对象
     * 
     * @param bucketName       桶
     * @param objectName       对象
     * @param sourceObjectList 组合组合的源对象列表
     * @param consumer         builder消费
     * @return
     */
    public ObjectWriteResponse composeObject(String bucketName, String objectName, List<ComposeSource> sourceObjectList,
            Consumer<ComposeObjectArgs.Builder> consumer) {
        try {
            ComposeObjectArgs.Builder builder = ComposeObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .sources(sourceObjectList);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.composeObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 组合源对象列表, 通过使用服务器端副本组合来自不同源对象的数据来创建对象,服务器上已存在的对象列表再次组合成一个对象
     * 
     * @param bucketName       桶
     * @param objectName       对象
     * @param sourceObjectList 组合组合的源对象列表
     * @return
     */
    public ObjectWriteResponse composeObject(String bucketName, String objectName,
            List<ComposeSource> sourceObjectList) {
        return composeObject(bucketName, objectName, sourceObjectList, null);
    }

    /**
     * 复制对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param source     源对象
     * @param consumer   builder消费
     * @return
     */
    public ObjectWriteResponse copyObject(String bucketName, String objectName, CopySource source,
            Consumer<CopyObjectArgs.Builder> consumer) {
        try {
            CopyObjectArgs.Builder builder = CopyObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .source(source);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.copyObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 复制对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param source     源对象
     * @return
     */
    public ObjectWriteResponse copyObject(String bucketName, String objectName, CopySource source) {
        return copyObject(bucketName, objectName, source, null);
    }

    /**
     * 设置对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param tags       标签
     * @param consumer   builder消费
     */
    public void setObjectTags(String bucketName, String objectName, Tags tags,
            Consumer<SetObjectTagsArgs.Builder> consumer) {
        try {
            SetObjectTagsArgs.Builder builder = SetObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .tags(tags);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.setObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 设置对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param tags       标签
     */
    public void setObjectTags(String bucketName, String objectName, Tags tags) {
        setObjectTags(bucketName, objectName, tags, null);
    }

    /**
     * 获取对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public Tags getObjectTags(String bucketName, String objectName, Consumer<GetObjectTagsArgs.Builder> consumer) {
        try {
            GetObjectTagsArgs.Builder builder = GetObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public Tags getObjectTags(String bucketName, String objectName) {
        return getObjectTags(bucketName, objectName, null);
    }

    /**
     * 删除对象标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     */
    public void deleteObjectTags(String bucketName, String objectName,
            Consumer<DeleteObjectTagsArgs.Builder> consumer) {
        try {
            DeleteObjectTagsArgs.Builder builder = DeleteObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.deleteObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 删除对象标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     */
    public void deleteObjectTags(String bucketName, String objectName) {
        deleteObjectTags(bucketName, objectName, null);
    }

    /**
     * 删除单个对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     */
    public void deleteObject(String bucketName, String objectName, Consumer<RemoveObjectArgs.Builder> consumer) {
        try {
            RemoveObjectArgs.Builder builder = RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.removeObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 删除单个对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     */
    public void deleteObject(String bucketName, String objectName) {
        deleteObject(bucketName, objectName, null);
    }

    /**
     * 删除多个对象
     * 
     * @param bucketName  桶
     * @param objectNames 对象列表
     * @param consumer    builder消费
     */
    public List<DeleteError> deleteObjects(String bucketName, List<DeleteObject> objectNames,
            Consumer<RemoveObjectsArgs.Builder> consumer) {
        try {
            RemoveObjectsArgs.Builder builder = RemoveObjectsArgs.builder()
                    .bucket(bucketName)
                    .objects(objectNames);
            if (consumer != null) {
                consumer.accept(builder);
            }
            Iterable<Result<DeleteError>> iterable = client.removeObjects(builder.build());
            return StreamSupport.stream(iterable.spliterator(), true).map(result -> {
                try {
                    return result.get();
                } catch (InvalidKeyException | ErrorResponseException | IllegalArgumentException
                        | InsufficientDataException | InternalException | InvalidResponseException
                        | NoSuchAlgorithmException | ServerException | XmlParserException | IOException e) {
                    throw new MinioRuntimeException(e);
                }
            }).collect(Collectors.toList());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 删除多个对象
     * 
     * @param bucketName  桶
     * @param objectNames 对象列表
     * @return
     */
    public List<DeleteError> deleteObjects(String bucketName, List<DeleteObject> objectNames) {
        return deleteObjects(bucketName, objectNames, null);
    }
}

megrez.boot.autoconfigure.minio.MinioBucketClient桶操作服务

@RequiredArgsConstructor
public class MinioBucketClient {
    private final MinioClient client;

    /**
     * 桶是否存在
     * 
     * @param bucketName 桶名
     * @param consumer   builder消费
     * @return
     */
    public boolean bucketExists(String bucketName, Consumer<BucketExistsArgs.Builder> consumer) {
        try {
            BucketExistsArgs.Builder builder = BucketExistsArgs.builder()
                    .bucket(bucketName);

            if (consumer != null) {
                consumer.accept(builder);
            }

            return client.bucketExists(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 桶是否存在
     * 
     * @param bucketName 桶名
     * @return
     */
    public boolean bucketExists(String bucketName) {
        return bucketExists(bucketName, null);
    }

    /**
     * 所有桶信息
     * 
     * @return
     */
    public List<Bucket> listBuckets() {
        try {
            return client.listBuckets();
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }

    }

    /**
     * 创建桶 
     * 
     * @param bucketName 桶名
     * @param consumer builder消费
     */
    public void makeBucket(String bucketName, Consumer<MakeBucketArgs.Builder> consumer) {
        try {
            MakeBucketArgs.Builder builder = MakeBucketArgs.builder()
                    .bucket(bucketName);

            if (consumer != null) {
                consumer.accept(builder);
            }

            client.makeBucket(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }

    }

    /**
     * 创建桶 
     * 
     * @param bucketName 桶名
     */
    public void makeBucket(String bucketName) {
        makeBucket(bucketName, null);
    }


    /**
     * 获取存储桶中的对象锁定配置
     * 
     * @param bucketName 桶名
     * @param consumer   builder消费
     * @return
     */
    public ObjectLockConfiguration getObjectLockConfiguration(String bucketName,
            Consumer<GetObjectLockConfigurationArgs.Builder> consumer) {
        try {
            GetObjectLockConfigurationArgs.Builder builder = GetObjectLockConfigurationArgs.builder()
                    .bucket(bucketName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObjectLockConfiguration(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取存储桶中的对象锁定配置
     * 
     * @param bucketName 桶名
     * @return
     */
    public ObjectLockConfiguration getObjectLockConfiguration(String bucketName) {
        return getObjectLockConfiguration(bucketName, null);
    }
}

完整实现参考源代码

还有更多的项目参考,megrez-oss是对象存储服务,基于本地文件系统的存储,或基于MinIO的存储服务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
编程题中Python的输入和输出可以使用input()和print()函数进行操作。在Python3中,input()函数用于接收用户的输入,并且不会存在代码注入的风险。例如,可以使用input()函数接收班级名称、姓名和正在学习的编程语言,并使用print()函数将其输出。示例代码如下: ```python ClassId01 = input("班级名称:") NameId01 = input("姓名:") LangId01 = input("正在学习的编程语言:") print("我是来自{}班级的{};\n{}语言是应用广泛的计算机编程语言;\n{}语言的学习需要大量的编程练习。".format(ClassId01, NameId01, LangId01, LangId01)) ``` 另外,如果需要进行多行多组输入,可以使用循环来实现。首先确定输入的行数,然后使用for循环接收每一行的输入,并进行相应的处理。接下来,可以使用print()函数输出结果。例如,下面的示例代码中,首先输入一个数字确定行数,然后循环接收每一行的输入,将输入的数字进行拆分并转换为整数类型,最后使用print()函数输出结果。 ```python res = [] n = int(input("行数:")) for _ in range(n): try: line = input() except: break a, b = line.split() res.append(int(a), int(b)) for i in range(len(res)): print(res[i]) ``` 这样,就可以实现对输入的字符串反向和输出了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python练习题__基础输入输出](https://blog.csdn.net/weixin_69553582/article/details/129363207)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Python零基础入门习题(一)输入和输出](https://blog.csdn.net/Megrez_9/article/details/125436188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [笔试编程题的输入输出(Python)](https://blog.csdn.net/JohnJim0/article/details/120237907)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值