返回

Minio轻松搞定分片上传和断点续传,再也不用为文件上传发愁!

后端

利用 Minio 实现 SpringBoot 后端分片上传和断点续传

在实际开发中,上传大文件(如视频、图片)时,我们经常会遇到超时和断线等问题,影响用户体验。Minio 作为一款分布式对象存储服务,以其高可靠性、高性能和低成本的特性,可以轻松应对大文件上传和下载的需求。本文将详细介绍如何利用 Minio 在 SpringBoot 后端项目中实现分片上传和断点续传。

一、环境准备

  1. 导入 Maven 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.3.13</version>
</dependency>
  1. 配置 Minio 客户端
@Value("${minio.endpoint}")
private String endpoint;

@Value("${minio.accessKey}")
private String accessKey;

@Value("${minio.secretKey}")
private String secretKey;

@Value("${minio.bucketName}")
private String bucketName;

@Bean
public MinioClient minioClient() {
    return MinioClient.builder()
            .endpoint(endpoint)
            .credentials(accessKey, secretKey)
            .build();
}

二、实现分片上传

  1. 获取文件信息
// 获取文件大小
long fileSize = file.getSize();

// 计算分片大小
long partSize = 5 * 1024 * 1024; // 5MB

// 计算分片数量
int partCount = (int) (fileSize / partSize);
if (fileSize % partSize > 0) {
    partCount++;
}
  1. 上传分片
// 创建临时桶
minioClient.makeBucket(bucketName);

// 上传分片文件
for (int i = 0; i < partCount; i++) {
    // 计算分片起始位置和结束位置
    long startPosition = i * partSize;
    long endPosition = startPosition + partSize - 1;

    // 如果是最后一个分片,则将结束位置调整为文件大小减一
    if (i == partCount - 1) {
        endPosition = fileSize - 1;
    }

    // 上传分片文件
    minioClient.uploadPart(bucketName, file.getOriginalFilename(), file.getInputStream(), startPosition, endPosition);
}

三、实现断点续传

  1. 合并分片
// 合并分片文件
minioClient.mergeParts(bucketName, file.getOriginalFilename(), "1", partCount, null);

四、总结

通过利用 Minio 的分片上传和断点续传功能,我们可以大幅提升大文件的上传速度和可靠性,有效解决传统 HTTP 上传方式存在的痛点。

五、常见问题解答

  1. 如何选择合适的分片大小?

分片大小需要综合考虑文件大小、网络带宽和服务器性能等因素。一般来说,分片大小设置为 5-10MB 比较合适。

  1. 如何保证分片上传的完整性?

Minio 会对每个分片进行 MD5 校验,并记录每个分片的校验值。在合并分片时,Minio 会再次校验分片的完整性,确保文件内容没有被损坏。

  1. 断点续传的原理是什么?

断点续传通过记录每个分片上传的起始和结束位置,当上传中断时,可以从中断处继续上传,无需重新上传整个文件。

  1. 分片上传的并发度如何设置?

Minio 支持对分片上传进行并发控制,通过设置 PartUploadOptions.concurrentUploads() 方法可以指定同时上传的分片数量。

  1. 如何使用 Java 代码获取分片上传进度?
UploadPartResponse partResponse = minioClient.uploadPart(bucketName, file.getOriginalFilename(), file.getInputStream(), startPosition, endPosition);
long partUploadId = partResponse.partUploadId();
GetUploadPartResponse partInfo = minioClient.getUploadPart(bucketName, file.getOriginalFilename(), partUploadId);
System.out.println("分片上传进度:" + partInfo.bytesUploaded() + "/" + partInfo.bytesExpected());