java使用minio上传大文件

该文章已生成可运行项目,

目录

  1. 简介
  2. 前置条件
  3. 添加依赖
  4. 初始化 MinIO 客户端
  5. 分片上传流程
  6. 完整代码示例
  7. 注意事项

简介

当上传大文件(如超过100MB)至 MinIO 对象存储时,推荐使用分片上传(Multipart Upload)方案。该方案具有以下优势:

  • 支持断点续传
  • 降低单次内存占用
  • 提升网络传输稳定性
  • 允许并行上传分片

前置条件

  1. 运行中的 MinIO 服务(本地或远程)
  2. Java 8+ 开发环境
  3. Maven/Gradle 项目

添加依赖

Maven 配置

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.7</version> 
</dependency>

Gradle 配置

implementation 'io.minio:minio:8.5.7'

初始化 MinIO 客户端

import io.minio.MinioClient;

public class MinioUploader {
    private static final String ENDPOINT = "http://localhost:9000";
    private static final String ACCESS_KEY = "your-access-key";
    private static final String SECRET_KEY = "your-secret-key";
    private static final String BUCKET_NAME = "uploads";

    private static MinioClient minioClient;

    public static void init() throws Exception {
        minioClient = MinioClient.builder()
                .endpoint(ENDPOINT)
                .credentials(ACCESS_KEY, SECRET_KEY)
                .build();
        
        // 确保存储桶存在
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());
        }
    }
}

分片上传流程

5.1 初始化分片上传

String objectName = "large-file.zip";
String uploadId = minioClient.createMultipartUpload(
        BUCKET_NAME,
        null,
        objectName,
        null,
        null
).result().uploadId();

5.2 分片文件上传

File file = new File("/path/to/large-file.zip");
long chunkSize = 50 * 1024 * 1024; // 50MB分片
int partNumber = 1;
Map<Integer, String> etags = new HashMap<>();

try (FileInputStream fis = new FileInputStream(file)) {
    byte[] buffer = new byte[(int) chunkSize];
    int bytesRead;
    
    while ((bytesRead = fis.read(buffer)) != -1) {
        ByteArrayInputStream partStream = new ByteArrayInputStream(buffer, 0, bytesRead);
        
        UploadPartResponse response = minioClient.uploadPart(
                BUCKET_NAME,
                null,
                objectName,
                uploadId,
                partNumber,
                partStream,
                bytesRead,
                null
        );
        
        etags.put(partNumber, response.etag());
        partNumber++;
    }
}

5.3 合并分片

List<Part> parts = new ArrayList<>();
for (int i = 1; i < partNumber; i++) {
    parts.add(new Part(i, etags.get(i)));
}

minioClient.completeMultipartUpload(
        BUCKET_NAME,
        null,
        objectName,
        uploadId,
        parts.toArray(new Part[0]),
        null,
        null
);

完整代码示例

public class MinioMultipartUploader {
    // 初始化代码...

    public static void uploadLargeFile(String filePath) throws Exception {
        init();
        File file = new File(filePath);
        String objectName = file.getName();
        
        // 初始化上传
        String uploadId = initializeMultipartUpload(objectName);
        
        // 分片上传
        Map<Integer, String> etags = uploadParts(objectName, uploadId, file);
        
        // 合并分片
        completeUpload(objectName, uploadId, etags);
    }

    private static String initializeMultipartUpload(String objectName) throws Exception {
        return minioClient.createMultipartUpload(
                BUCKET_NAME,
                null,
                objectName,
                null,
                null
        ).result().uploadId();
    }

    private static Map<Integer, String> uploadParts(String objectName, String uploadId, File file) throws Exception {
        // 分片上传实现...
    }

    private static void completeUpload(String objectName, String uploadId, Map<Integer, String> etags) throws Exception {
        // 合并实现...
    }
}

注意事项

  1. 分片大小:每个分片最小5MB(最后分片除外)
  2. 临时文件管理:建议使用临时目录存储分片
  3. 异常处理
    • 捕获所有 MinIO 异常
    • 实现上传进度记录
    • 添加重试机制
  4. 网络优化
    MinioClient.builder()
        .endpoint(endpoint)
        .credentials(accessKey, secretKey)
        .httpClient(HttpClient.newBuilder()
                .connectTimeout(Duration.ofMinutes(5))
                .build())
        .build();
    
  5. 清理资源:及时关闭文件流和临时流
本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值