Minio入门系列【6】JAVA集成Minio之对象操作API使用详解

1 上传对象

1.1 PutObject

调用PutObject接口上传文件(Object)

public ObjectWriteResponse putObject(PutObjectArgs args)

注意事项:

  • 添加的Object大小不能超过5 GB。

  • 默认情况下,如果已存在同名Object且对该Object有访问权限,则新添加的Object将覆盖原有的Object,并返回200 OK。

  • OSS没有文件夹的概念,所有资源都是以文件来存储,但您可以通过创建一个以正斜线(/)结尾,大小为0的Object来创建模拟文件夹。

示例1,InputStream上传:

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        putObject(new File("C:\\Users\\1\\Desktop\\minio.jpg"), "mall4cloud");
    }

    /**
     * 上传文件
     *
     * @param file 需要上传的文件
     * @param bucket 桶名称
     */
    public static void putObject(File file ,String bucket) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = Files.newInputStream(file.toPath());
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(file.getName()).stream(
                                inputStream, inputStream.available(), -1)
                        .build());
        inputStream.close();
    }

示例2,InputStream使用SSE-C加密上传(后续会介绍):

            minioClient.putObject(                  PutObjectArgs.builder().bucket("mall4cloud").object(file.getName()).stream(
                            bais, bais.available(), -1)
                            .sse(ssec)
                            .build());
            bais.close();

示例3,InputStream上传文件,添加自定义元数据及消息头:

    /**
     * 上传文件(InputStream上传文件,添加自定义元数据及消息头)
     *
     * @param file 需要上传的文件
     * @param bucket 桶名称
     */
    public static void putObject(File file ,String bucket, Map<String, String> headers) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = Files.newInputStream(file.toPath());
        Map<String, String> userMetadata = new HashMap<>();
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(file.getName()).stream(
                                inputStream, inputStream.available(), -1)
                        .headers(headers)
                        .userMetadata(userMetadata)
                        .build());
        inputStream.close();
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/octet-stream");
        headers.put("X-Amz-Storage-Class", "REDUCED_REDUNDANCY");
        putObject(new File("C:\\Users\\1\\Desktop\\minio.jpg"), "mall4cloud", headers);
    }

1.2 uploadObject

将文件中的内容作为存储桶中的对象上传。

public void uploadObject(UploadObjectArgs args)

示例:

            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket("mall4cloud")
                            .object("minio.jpg")
                            .filename("C:\\Users\\1\\Desktop\\minio.jpg")
                            .build());

2 获取对象

2.1 getObject

GetObject接口用于获取某个文件(Object)。此操作需要对此Object具有读权限。

获取对象的数据。InputStream使用后返回必须关闭以释放网络资源。

public InputStream getObject(GetObjectArgs args)

示例:

    /**
     * 获取文件
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param targetPath 存储的路径
     */
    public static void getObject(String bucket, String filename, String targetPath) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream stream =
                minioClient.getObject(
                        GetObjectArgs.builder().bucket(bucket).object(filename).build());
        // 读流
        File targetFile = new File(targetPath);
        FileUtils.copyInputStreamToFile(stream, targetFile);
        stream.close();
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        getObject("mall4cloud", "minio.jpg", "C:\\Users\\1\\Desktop\\minio2.jpg");
    }

2.2 downloadObject

将对象的数据下载到文件。

public void downloadObject(DownloadObjectArgs args) 

示例:

    /**
     * 下载文件
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param targetPath 存储的路径
     */
    public static void downloadObject(String bucket, String filename, String targetPath) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.downloadObject(
                DownloadObjectArgs.builder()
                        .bucket(bucket)
                        .object(filename)
                        .filename(targetPath)
                        .build());
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        downloadObject("mall4cloud", "minio.jpg", "C:\\Users\\1\\Desktop\\minio2.jpg");
    }

2.3 getPresignedObjectUrl

获取一个指定了 HTTP 方法、到期时间和自定义请求参数的对象URL地址,也就是返回带签名的URL,这个地址可以提供给没有登录的第三方共享访问或者上传对象。

public String getPresignedObjectUrl(GetPresignedObjectUrlArgs args) 

示例:

    /**
     * 获取文件url
     *
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static String getPresignedObjectUrl(String bucket, String filename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucket)
                        .object(filename)
                        .expiry(60 * 60 * 24)
                        .build());
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        System.out.println(getPresignedObjectUrl("mall4cloud", "minio.jpg"));
    }

2.4 selectObjectContent

通过 SQL 表达式选择对象的内容。

public SelectResponseStream selectObjectContent(SelectObjectContentArgs args)

示例:
上传一个文件,文件内容为:
Minio入门系列【6】JAVA集成Minio之对象操作API使用详解_第1张图片
示例:

    /**
     * 通过 SQL 表达式选择对象的内容
     *
     * @param data 上传的数据
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static String selectObjectContent(byte[] data, String bucket, String filename) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 1. 上传一个文件
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(filename).stream(
                                byteArrayInputStream, data.length, -1)
                        .build());
        // 调用SQL表达式获取对象
        String sqlExpression = "select * from S3Object";
        InputSerialization is =
                new InputSerialization(null, false, null, null, FileHeaderInfo.USE, null, null, null);
        OutputSerialization os =
                new OutputSerialization(null, null, null, QuoteFields.ASNEEDED, null);
        SelectResponseStream stream =
                minioClient.selectObjectContent(
                        SelectObjectContentArgs.builder()
                                .bucket(bucket)
                                .object(filename)
                                .sqlExpression(sqlExpression)
                                .inputSerialization(is)
                                .outputSerialization(os)
                                .requestProgress(true)
                                .build());

        byte[] buf = new byte[512];
        int bytesRead = stream.read(buf, 0, buf.length);
        return new String(buf, 0, bytesRead, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        List<String> stringList = FileUtil.readLines("C:\\Users\\1\\Desktop\\test.txt", StandardCharsets.UTF_8);
        System.out.println(selectObjectContent(String.join("\n", stringList).getBytes(), "mall4cloud", "test.txt"));
    }

2.5 getPresignedPostFormData

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

一般可用于,前端请求一个上传策略,后端返回给前端,前端使用Post请求+访问策略去上传文件,这可以用于JS+SDK的混合方式集成minio

Minio入门系列【6】JAVA集成Minio之对象操作API使用详解_第2张图片

public Map<String,String> getPresignedPostFormData(PostPolicy policy)

示例,首先我们创建一个Post 策略,然后,第三方就可以使用这些策略,直接使用POST上传对象,代码如下:

    /**
     * 设置并获取Post策略
     *
     * @param bucket 桶名
     */
    public static Map<String, String> setPostPolicy(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 为存储桶创建一个上传策略,过期时间为7天
        PostPolicy policy = new PostPolicy(bucket, ZonedDateTime.now().plusDays(7));
        // 设置一个参数key,值为上传对象的名称
        policy.addEqualsCondition("key", bucket);
        // 添加Content-Type以"image/"开头,表示只能上传照片
        policy.addStartsWithCondition("Content-Type", "image/");
        // 设置上传文件的大小 64kiB to 10MiB.
        policy.addContentLengthRangeCondition(64 * 1024, 10 * 1024 * 1024);
        return minioClient.getPresignedPostFormData(policy);
    }

    /**
     * 使用Post上传
     * 
     * @param formData Post策略
     * @param url minio服务器地址
     * @param bucket 桶名
     * @param path 本地文件地址
     */
    public static boolean uploadByHttp(Map<String, String> formData, String url, String bucket, String path) throws IOException {
        // 创建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", bucket);
        multipartBuilder.addFormDataPart("Content-Type", "image/png");
        multipartBuilder.addFormDataPart(
                "file", "my-objectname", RequestBody.create(new File(path), null));
        // 模拟第三方,使用OkHttp调用Post上传对象
        Request request =
                new Request.Builder()
                        .url(url + "/" + bucket)
                        .post(multipartBuilder.build())
                        .build();
        OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
        Response response = httpClient.newCall(request).execute();
        return response.isSuccessful();
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        String bucket = "mall4cloud";
        //第一步:设置并获取Post策略
        Map<String, String> formData = setPostPolicy(bucket);
        //第二步:使用Post请求上传对象
        uploadByHttp(formData, url, bucket, "C:\\Users\\1\\Desktop\\minio.jpg");
    }

3 复制对象

3.1 copyObject

通过服务器端从另一个对象复制数据来创建一个对象

public ObjectWriteResponse copyObject(CopyObjectArgs args)

示例:

    /**
     * 对象拷贝
     *
     * @param sourceBucket 源对象桶
     * @param sourceFilename 源文件名
     * @param targetBucket 目标对象桶
     * @param targetFilename 目标文件名
     */
    public static void copyObject(String sourceBucket, String sourceFilename, String targetBucket, String targetFilename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.copyObject(
                CopyObjectArgs.builder()
                        .bucket(targetBucket)
                        .object(targetFilename)
                        .source(CopySource.builder()
                                        .bucket(sourceBucket)
                                        .object(sourceFilename)
                                        .build())
                        .build());
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        copyObject("mall4cloud", "minio.jpg", "mall4cloud", "minioCopy.jpg");
    }

4 删除对象

4.1 removeObject

移除一个对象

public void removeObject(RemoveObjectArgs args) 

示例:

    /**
     * 删除单个对象
     *
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static void removeObject(String bucket, String filename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.removeObject(
                RemoveObjectArgs.builder().bucket(bucket).object(filename).build());
    }

    /**
     * 删除指定版本号的对象
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param versionId 版本号
     */
    public static void removeObject(String bucket, String filename, String versionId) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucket)
                        .object(filename)
                        .versionId(versionId)
                        .build());
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        removeObject("mall4cloud", "minioCopy.jpg");
    }

4.2 emoveObjects

懒惰地删除多个对象。它需要迭代返回的 Iterable 以执行删除。

public Iterable<Result<DeleteError>> removeObjects(RemoveObjectsArgs args) 

示例:

    /**
     * 删除多个文件
     * 
     * @param bucket 桶名称
     * @param filenames 文件名列表
     * @return 返回每个文件的执行情况
     */
    public static Iterable<Result<DeleteError>> removeObjects(String bucket, List<String> filenames){
        if (ObjectUtils.isEmpty(filenames)) {
            return new LinkedList<>();
        }
        // 7. 删除多个文件
        List<DeleteObject> objects = new LinkedList<>();
        filenames.forEach(filename-> objects.add(new DeleteObject(filename)));
        return minioClient.removeObjects(
                RemoveObjectsArgs.builder().bucket(bucket).objects(objects).build());
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        List<String> filenames = new ArrayList<>();
        filenames.add("minioCopy.jpg");
        Iterable<Result<DeleteError>> resultList = removeObjects("mall4cloud", filenames);
        for (Result<DeleteError> result : resultList) {
            DeleteError error = result.get();
            System.out.println(
                    "Error in deleting object " + error.objectName() + "; " + error.message());
        }
    }

5 对象信息查询及设置

5.1 桶的对象信息列表

listObjects列出桶的对象信息

public Iterable<Result<Item>> listObjects(ListObjectsArgs args)

示例1,查询存储桶下文件信息:

 Iterable<Result<Item>> results =
                    minioClient.listObjects(ListObjectsArgs.builder().bucket("my-bucketname").build());
            for (Result<Item> result : results) {
                Item item = result.get();
                System.out.println(item.lastModified() + "\t" + item.size() + "\t" + item.objectName());
            }

示例2,递归查询存储桶下文件信息:

Iterable<Result<Item>> results =
                    minioClient.listObjects(
                            ListObjectsArgs.builder().bucket("my-bucketname").recursive(true).build());

            for (Result<Item> result : results) {
                Item item = result.get();
                System.out.println(item.lastModified() + "\t" + item.size() + "\t" + item.objectName());
            }

示例3, 条件查询,指定前缀、后缀、最大数量:

// 条件查询,指定前缀、后缀、最大数量
            Iterable<Result<Item>> results =
                    minioClient.listObjects(
                            ListObjectsArgs.builder()
                                    .bucket("my-bucketname")
                                    .startAfter("ExampleGuide.pdf")
                                    .prefix("E")
                                    .maxKeys(100)
                                    .build());

            for (Result<Item> result : results) {
                Item item = result.get();
                System.out.println(item.lastModified() + "\t" + item.size() + "\t" + item.objectName());

5.2 保留配置

获取对象的保留配置

public Retention getObjectRetention(GetObjectRetentionArgs args) 

示例:

  // 获取对象保留配置
            Retention retention =
                    minioClient.getObjectRetention(
                            GetObjectRetentionArgs.builder()
                                    .bucket("my-bucketname-in-eu-with-object-lock")
                                    .object("k3s-arm64")
                                    .build());

            System.out.println("Mode: " + retention.mode());
            System.out.println("Retainuntil Date: " + retention.retainUntilDate());

添加对象的保留配置,存储桶需要设置为对象锁定模式,并且没有开启版本控制,否则会报错收蠕虫保护。

public void setObjectLockRetention(SetObjectRetentionArgs)
// 对象保留配置,保留至当前日期后3天。
            ZonedDateTime retentionUntil = ZonedDateTime.now(Time.UTC).plusDays(3).withNano(0);
            Retention retention1 = new Retention(RetentionMode.COMPLIANCE, retentionUntil);
            minioClient.setObjectRetention(
                    SetObjectRetentionArgs.builder()
                            .bucket("my-bucketname-in-eu-with-object-lock")
                            .object("k3s-arm64")
                            .config(retention1)
                            .bypassGovernanceMode(true)
                            .build());

5.3 标签

为对象设置标签

public void setObjectTags(SetObjectTagsArgs args)

示例:

Map<String, String> map = new HashMap<>();
            map.put("Project", "Project One");
            map.put("User", "jsmith");
            minioClient.setObjectTags(
                    SetObjectTagsArgs.builder()
                            .bucket("my-bucketname")
                            .object("my-objectname")
                            .tags(map)
                            .build());

获取对象的标签。

public Tags getObjectTags(GetObjectTagsArgs args) 

示例:

Tags tags = minioClient.getObjectTags(
                            GetObjectTagsArgs.builder().bucket("my-bucketname").object("my-objectname").build());
System.out.println("Object tags: " + tags.get());

删除对象的标签。

private void deleteObjectTags(DeleteObjectTagsArgs args)

示例:

 minioClient.deleteObjectTags(
          DeleteObjectTagsArgs.builder().bucket("my-bucketname").object("my-objectname").build());
      System.out.println("Object tags deleted successfully");

5.4 合法保留对象

启用对对象的合法保留

public void enableObjectLegalHold(EnableObjectLegalHoldArgs args) 

案例:

 minioClient.enableObjectLegalHold(
          EnableObjectLegalHoldArgs.builder()
              .bucket("my-bucketname")
              .object("my-objectname")
              .versionId("object-versionId")
              .build());

      System.out.println("Legal hold enabled on object successfully ");

禁用对对象的合法保留

public void disableObjectLegalHold(DisableObjectLegalHoldArgs args)

示例:

minioClient.disableObjectLegalHold(
          DisableObjectLegalHoldArgs.builder()
              .bucket("my-bucketname")
              .object("my-objectname")
              .build());
      System.out.println("Legal hold disabled on object successfully ");

5.5 组合对象

通过使用服务器端副本组合来自不同源对象的数据来创建对象,比如可以将文件分片上传,然后将他们合并为一个文件。

public ObjectWriteResponse composeObject(ComposeObjectArgs args)

示例:

List<ComposeSource> sources = new ArrayList<ComposeSource>();
        sources.add(
            ComposeSource.builder()
                .bucket("my-bucketname-one")
                .object("my-objectname-one")
                .build());
        sources.add(
            ComposeSource.builder()
                .bucket("my-bucketname-two")
                .object("my-objectname-two")
                .build());

        minioClient.composeObject(
            ComposeObjectArgs.builder()
                .bucket("my-destination-bucket")
                .object("my-destination-object")
                .sources(sources)
                .build());
        System.out.println("Object Composed successfully");

5.6 元数据

获取对象的对象信息和元数据

public ObjectStat statObject(StatObjectArgs args)

示例:

StatObjectResponse stat =
                    minioClient.statObject(
                            StatObjectArgs.builder()
                                    .bucket("my-bucketname")
                                    .object("start.sh")
                                    .build());
            System.out.println(stat.toString());

6 工具类参考

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.*;
import okhttp3.*;
import org.apache.commons.io.FileUtils;
import org.springframework.util.ObjectUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * minio对象操作工具类
 *
 * @author wuKeFan
 * @date 2023-09-19 09:45:43
 */
public class MinioObjectUtil {

    /**
     * minio地址(自己填写)
     */
    private static final String url = "url";

    /**
     * minio用户名(自己填写)
     */
    private static final String accessKey = "accessKey";

    /**
     * minio密码(自己填写)
     */
    private static final String secretKey = "secretKey";

    private static final MinioClient minioClient;

    static {
        minioClient = MinioClient.builder().endpoint(url)
                .credentials(accessKey, secretKey).build();
    }

    /**
     * 上传文件(InputStream上传)
     *
     * @param file 需要上传的文件
     * @param bucket 桶名称
     */
    public static void putObject(File file ,String bucket) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = Files.newInputStream(file.toPath());
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(file.getName()).stream(
                                inputStream, inputStream.available(), -1)
                        .build());
        inputStream.close();
    }

    /**
     * 上传文件(InputStream使用SSE-C加密上传)
     *
     * @param file 需要上传的文件
     * @param bucket 桶名称
     */
    public static void putObject(File file ,String bucket, ServerSideEncryption ssec) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = Files.newInputStream(file.toPath());
        minioClient.putObject(
                PutObjectArgs.builder().bucket("mall4cloud").object(file.getName()).stream(
                                inputStream, inputStream.available(), -1)
                        .sse(ssec)
                        .build());
        inputStream.close();
    }

    /**
     * 上传文件(InputStream上传文件,添加自定义元数据及消息头)
     *
     * @param file 需要上传的文件
     * @param bucket 桶名称
     */
    public static void putObject(File file ,String bucket, Map<String, String> headers) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream inputStream = Files.newInputStream(file.toPath());
        Map<String, String> userMetadata = new HashMap<>();
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(file.getName()).stream(
                                inputStream, inputStream.available(), -1)
                        .headers(headers)
                        .userMetadata(userMetadata)
                        .build());
        inputStream.close();
    }

    /**
     * 获取文件
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param targetPath 存储的路径
     */
    public static void getObject(String bucket, String filename, String targetPath) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        InputStream stream =
                minioClient.getObject(
                        GetObjectArgs.builder().bucket(bucket).object(filename).build());
        // 读流
        File targetFile = new File(targetPath);
        FileUtils.copyInputStreamToFile(stream, targetFile);
        stream.close();
    }

    /**
     * 下载文件
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param targetPath 存储的路径
     */
    public static void downloadObject(String bucket, String filename, String targetPath) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.downloadObject(
                DownloadObjectArgs.builder()
                        .bucket(bucket)
                        .object(filename)
                        .filename(targetPath)
                        .build());
    }

    /**
     * 获取文件url
     *
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static String getPresignedObjectUrl(String bucket, String filename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucket)
                        .object(filename)
                        .expiry(60 * 60 * 24)
                        .build());
    }

    /**
     * 通过 SQL 表达式选择对象的内容
     *
     * @param data 上传的数据
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static String selectObjectContent(byte[] data, String bucket, String filename) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 1. 上传一个文件
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucket).object(filename).stream(
                                byteArrayInputStream, data.length, -1)
                        .build());
        // 调用SQL表达式获取对象
        String sqlExpression = "select * from S3Object";
        InputSerialization is =
                new InputSerialization(null, false, null, null, FileHeaderInfo.USE, null, null, null);
        OutputSerialization os =
                new OutputSerialization(null, null, null, QuoteFields.ASNEEDED, null);
        SelectResponseStream stream =
                minioClient.selectObjectContent(
                        SelectObjectContentArgs.builder()
                                .bucket(bucket)
                                .object(filename)
                                .sqlExpression(sqlExpression)
                                .inputSerialization(is)
                                .outputSerialization(os)
                                .requestProgress(true)
                                .build());

        byte[] buf = new byte[512];
        int bytesRead = stream.read(buf, 0, buf.length);
        return new String(buf, 0, bytesRead, StandardCharsets.UTF_8);
    }

    /**
     * 设置并获取Post策略
     *
     * @param bucket 桶名
     */
    public static Map<String, String> setPostPolicy(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 为存储桶创建一个上传策略,过期时间为7天
        PostPolicy policy = new PostPolicy(bucket, ZonedDateTime.now().plusDays(7));
        // 设置一个参数key,值为上传对象的名称
        policy.addEqualsCondition("key", bucket);
        // 添加Content-Type以"image/"开头,表示只能上传照片
        policy.addStartsWithCondition("Content-Type", "image/");
        // 设置上传文件的大小 64kiB to 10MiB.
        policy.addContentLengthRangeCondition(64 * 1024, 10 * 1024 * 1024);
        return minioClient.getPresignedPostFormData(policy);
    }

    /**
     * 使用Post上传
     *
     * @param formData Post策略
     * @param url minio服务器地址
     * @param bucket 桶名
     * @param path 本地文件地址
     */
    public static boolean uploadByHttp(Map<String, String> formData, String url, String bucket, String path) throws IOException {
        // 创建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", bucket);
        multipartBuilder.addFormDataPart("Content-Type", "image/png");
        multipartBuilder.addFormDataPart(
                "file", "my-objectname", RequestBody.create(new File(path), null));
        // 模拟第三方,使用OkHttp调用Post上传对象
        Request request =
                new Request.Builder()
                        .url(url + "/" + bucket)
                        .post(multipartBuilder.build())
                        .build();
        OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
        Response response = httpClient.newCall(request).execute();
        return response.isSuccessful();
    }

    /**
     * 对象拷贝
     *
     * @param sourceBucket 源对象桶
     * @param sourceFilename 源文件名
     * @param targetBucket 目标对象桶
     * @param targetFilename 目标文件名
     */
    public static void copyObject(String sourceBucket, String sourceFilename, String targetBucket, String targetFilename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.copyObject(
                CopyObjectArgs.builder()
                        .bucket(targetBucket)
                        .object(targetFilename)
                        .source(CopySource.builder()
                                        .bucket(sourceBucket)
                                        .object(sourceFilename)
                                        .build())
                        .build());
    }

    /**
     * 删除单个对象
     *
     * @param bucket 桶名称
     * @param filename 文件名
     */
    public static void removeObject(String bucket, String filename) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        minioClient.removeObject(
                RemoveObjectArgs.builder().bucket(bucket).object(filename).build());
    }

    /**
     * 删除指定版本号的对象
     *
     * @param bucket 桶名称
     * @param filename 文件名
     * @param versionId 版本号
     */
    public static void removeObject(String bucket, String filename, String versionId) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucket)
                        .object(filename)
                        .versionId(versionId)
                        .build());
    }

    /**
     * 删除多个文件
     *
     * @param bucket 桶名称
     * @param filenames 文件名列表
     * @return 返回每个文件的执行情况
     */
    public static Iterable<Result<DeleteError>> removeObjects(String bucket, List<String> filenames){
        if (ObjectUtils.isEmpty(filenames)) {
            return new LinkedList<>();
        }
        // 7. 删除多个文件
        List<DeleteObject> objects = new LinkedList<>();
        filenames.forEach(filename-> objects.add(new DeleteObject(filename)));
        return minioClient.removeObjects(
                RemoveObjectsArgs.builder().bucket(bucket).objects(objects).build());
    }

    public static void main(String[] args) {

    }

}

你可能感兴趣的:(Minio,微服务,java,minio,分布式,分布式图片,对象存储)