MinIO Java Client API 完整参考文档(含概念解释)
来源:https://minio.org.cn/docs/minio/linux/developers/java/API.html
整理日期:2026-08-02
一、MinIO 是什么?
MinIO 是一个兼容 Amazon S3 API 的对象存储服务。简单说,它就像一个云端的文件系统,但文件不是按目录层级存的,而是按"桶(Bucket)+ 对象(Object)"的扁平结构存。
| 概念 | 类比 | 说明 |
|---|---|---|
| Bucket(桶) | 类似文件系统的"根目录" | 存放对象的容器,每个 MinIO 可以有多个桶 |
| Object(对象) | 类似"文件" | 实际存储的数据,包含数据本身 + 元数据(大小、类型、标签等) |
二、客户端构建器
创建 MinioClient 实例,所有 API 操作的入口。
java
MinioClient minioClient = MinioClient.builder()
.endpoint("https://play.min.io") // MinIO 服务地址
.credentials("accessKey", "secretKey") // 账号密钥(类似用户名+密码)
.region("us-west-1") // 可选,区域
.build();
| 参数 | 说明 |
|---|---|
endpoint |
MinIO 服务的 URL 地址,例如 http://localhost:9000 |
credentials |
Access Key (访问密钥,类似用户名)和 Secret Key(私有密钥,类似密码) |
region |
区域名称,如不指定则自动探测 |
httpClient |
可注入自定义 HTTP 客户端(如配置代理、超时等) |
三、核心概念一:桶策略(Bucket Policy)⭐
这是什么?
桶策略 就是一套 "谁能对这个桶做什么" 的访问控制规则。它是一段 JSON 格式的 IAM(Identity and Access Management)策略文档。
为什么需要?
默认情况下,MinIO 的桶是私有的 ------只有拥有 Access Key 的人才能访问。如果你想让某些对象公开可访问(比如网站图片),或者只允许特定用户操作,就需要配置策略。
示例解读
json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow", // 效果:允许
"Principal": "*", // 谁:* = 所有人(匿名用户)
"Action": ["s3:GetBucketLocation", "s3:ListBucket"], // 能做什么:列出桶
"Resource": "arn:aws:s3:::my-bucketname" // 对哪个桶生效
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject", // 能做什么:下载对象
"Resource": "arn:aws:s3:::my-bucketname/myobject*" // 只对 myobject* 开头的文件
}
]
}
这段策略的意思是:
允许任何人 (不登录)列出桶里的文件 ,并且可以下载
myobject*开头的文件。但其他操作(如上传、删除)仍然不允许。
策略 JSON 结构说明
| 字段 | 含义 | 常见值 |
|---|---|---|
Effect |
效果 | Allow(允许)或 Deny(拒绝) |
Principal |
谁 | "*" 表示所有人;也可指定具体用户 ARN |
Action |
什么操作 | s3:GetObject(下载)、s3:PutObject(上传)、s3:ListBucket(列出)等 |
Resource |
对哪个资源 | arn:aws:s3:::桶名 或 arn:aws:s3:::桶名/对象前缀* |
对应 API
java
// 设置策略
minioClient.setBucketPolicy(
SetBucketPolicyArgs.builder()
.bucket("my-bucketname")
.config(policyJson) // 上面的 JSON 字符串
.build());
// 获取当前策略
String policy = minioClient.getBucketPolicy(
GetBucketPolicyArgs.builder().bucket("my-bucketname").build());
// 删除策略(恢复默认:只有拥有密钥的人能访问)
minioClient.deleteBucketPolicy(
DeleteBucketPolicyArgs.builder().bucket("my-bucketname").build());
四、核心概念二:版本控制(Versioning)
这是什么?
启用后,MinIO 会保留同一个对象的每一个历史版本,而不是直接覆盖。每次上传同名对象,旧版本不会被删除,而是被标记为"旧版本"。
什么场景用?
- 误删恢复:不小心删了文件,可以回滚到上一个版本
- 审计合规:需要保留所有修改记录
- 防止覆盖:重要文件不希望被意外覆盖
对应 API
java
// 启用版本控制
VersioningConfiguration config = new VersioningConfiguration(
VersioningConfiguration.Status.ENABLED, true);
minioClient.setBucketVersioning(
SetBucketVersioningArgs.builder().bucket("my-bucketname").config(config).build());
// 查看是否启用
VersioningConfiguration config = minioClient.getBucketVersioning(
GetBucketVersioningArgs.builder().bucket("my-bucketname").build());
五、核心概念三:标签(Tags)
这是什么?
标签就是给桶或对象贴的键值对分类标记 ,比如 "部门": "研发"、"项目": "XX系统",纯粹是元数据,不影响数据本身。
什么场景用?
- 成本核算 :按
部门标签统计各团队用了多少存储 - 批量操作:按标签批量删除、批量导出
- 权限控制:策略中可以按标签条件限制访问
对应 API
java
// 给桶打标签
Map<String, String> map = new HashMap<>();
map.put("Project", "Project One");
map.put("User", "jsmith");
minioClient.setBucketTags(
SetBucketTagsArgs.builder().bucket("my-bucketname").tags(map).build());
// 查询标签
Tags tags = minioClient.getBucketTags(
GetBucketTagsArgs.builder().bucket("my-bucketname").build());
// 删除标签
minioClient.deleteBucketTags(
DeleteBucketTagsArgs.builder().bucket("my-bucketname").build());
// 对象的标签操作同理:getObjectTags / setObjectTags / deleteObjectTags
六、核心概念四:加密(Encryption)
这是什么?
对桶中的对象进行服务端加密,数据写入磁盘时自动加密,读取时自动解密。一般用于合规要求(如 GDPR、等保)。
三种加密方式
| 方式 | 说明 |
|---|---|
| SSE-S3 | MinIO 用服务端统一密钥自动加密,对用户透明,最简单 |
| SSE-C | 用户自己提供加密密钥,上传下载时都要带这个密钥 |
| SSE-KMS | 对接外部密钥管理服务(如 HashiCorp Vault),集中管密钥 |
对应 API
java
// 设置桶的加密配置(之后上传到这个桶的对象都自动加密)
minioClient.setBucketEncryption(
SetBucketEncryptionArgs.builder().bucket("my-bucketname").config(config).build());
// 查看加密配置
SseConfiguration config = minioClient.getBucketEncryption(
GetBucketEncryptionArgs.builder().bucket("my-bucketname").build());
// 删除加密配置(后续上传不再自动加密)
minioClient.deleteBucketEncryption(
DeleteBucketEncryptionArgs.builder().bucket("my-bucketname").build());
七、核心概念五:生命周期(Lifecycle)
这是什么?
自动化的数据管理规则。你可以设定:"文件创建 30 天后自动转为低成本存储"、"日志文件 90 天后自动删除"。
什么场景用?
- 降成本:热数据 → 冷数据自动迁移(如 Standard → Glacier)
- 自动清理:临时文件、日志、备份到期自动删除,不用手动维护
- 合规归档:法规要求数据保留 N 年后才能删
示例解读
java
// 规则1: documents/ 下的文件,30天后自动转为 GLACIER 冷存储(便宜但读取得先恢复)
rules.add(new LifecycleRule(
Status.ENABLED, null, null, new RuleFilter("documents/"),
"rule1", null, null,
new Transition((ZonedDateTime) null, 30, "GLACIER")
));
// 规则2: logs/ 下的文件,365天后自动删除
rules.add(new LifecycleRule(
Status.ENABLED, null,
new Expiration((ZonedDateTime) null, 365, null),
new RuleFilter("logs/"),
"rule2", null, null, null
));
对应 API
同之前文档中的 setBucketLifecycle / getBucketLifecycle / deleteBucketLifecycle。
八、核心概念六:跨区域复制(Replication)
这是什么?
把一个桶的数据自动同步到另一个区域(甚至另一个 MinIO 集群)的桶中。数据写入源桶后,MinIO 自动拷贝到目标桶。
什么场景用?
- 异地灾备:一个机房挂掉,另一个机房还有数据
- 就近访问:北京用户访问北京节点,上海用户访问上海节点
- 合规要求:数据必须存放在特定地理区域
对应 API
同之前文档中的 setBucketReplication / getBucketReplication / deleteBucketReplication。
九、核心概念七:事件通知(Notification)
这是什么?
当桶里发生某些事件(上传、删除、访问等)时,MinIO 自动推送消息到指定的消息队列(如 Redis、Kafka、MySQL、Webhook 等)。
什么场景用?
- 自动处理上传的文件:上传图片 → 触发缩略图生成
- 审计日志:谁在什么时候删了什么文件,全记下来
- 实时同步:文件变更后通知下游服务
API 分两种
| API | 说明 |
|---|---|
setBucketNotification |
配置通知规则:什么事件、推送到哪里 |
listenBucketNotification |
监听事件:直接在代码中接收事件(不需要额外消息队列) |
java
// 代码中监听事件(轻量级,不需要消息队列)
String[] events = {"s3:ObjectCreated:*", "s3:ObjectAccessed:*"};
try (CloseableIterator<Result<NotificationRecords>> ci =
minioClient.listenBucketNotification(
ListenBucketNotificationArgs.builder()
.bucket("bucketName").prefix("").suffix("").events(events).build())) {
while (ci.hasNext()) {
NotificationRecords records = ci.next().get();
for (Event event : records.events()) {
System.out.println("事件 " + event.eventType() + " 发生于 "
+ event.eventTime() + " " + event.bucketName() + "/" + event.objectName());
}
}
}
十、核心概念八:对象锁(Object Lock)+ 合法保留(Legal Hold)
这是什么?
WORM (Write Once, Read Many)------写一次,读多次。意思是对象一旦写入,在规定时间内不可修改、不可删除 。常用于合规归档场景。
两个子功能
| 功能 | 说明 | 类比 |
|---|---|---|
| Retention(保留) | 设定保留期限,到期前不能删 | "这个合同保存 7 年,7 年内任何人不能删" |
| Legal Hold(合法保留) | 无限期的"冻结",直到手动解除 | "这个文件涉及诉讼,暂时不能删" |
保留模式
| 模式 | 说明 |
|---|---|
| COMPLIANCE | 严格合规模式,连 root 都不能在到期前删除 |
| GOVERNANCE | 治理模式,有特殊权限的人可以绕过 |
java
// 设置对象保留:COMPLIANCE 模式,保留1年
Retention retention = new Retention(RetentionMode.COMPLIANCE, ZonedDateTime.now().plusYears(1));
minioClient.setObjectRetention(
SetObjectRetentionArgs.builder()
.bucket("my-bucketname").object("my-objectname")
.config(retention)
.build());
// 启用合法保留(无限期冻结)
minioClient.enableObjectLegalHold(
EnableObjectLegalHoldArgs.builder()
.bucket("my-bucketname").object("my-objectname").build());
// 解除合法保留
minioClient.disableObjectLegalHold(
DisableObjectLegalHoldArgs.builder()
.bucket("my-bucketname").object("my-objectname").build());
// 删除对象时指定绕过保留策略(需要对应权限)
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket("my-bucketname").object("my-objectname")
.bypassRetentionMode(true) // 绕过治理模式
.build());
十一、核心概念九:预签名 URL(Presigned URL)
这是什么?
生成一个临时有效的 URL ,拿到这个 URL 的人可以在不登录 MinIO 的情况下下载或上传文件。
什么场景用?
- 用户临时下载:你生成一个 2 小时有效的下载链接发给用户,过期就失效
- 前端直传:后端生成上传 URL,前端直接上传到 MinIO,不经过后端服务器(省带宽)
java
// 生成一个 2 小时内有效的下载链接
String url = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET) // HTTP GET = 下载
.bucket("my-bucketname")
.object("my-objectname")
.expiry(2, TimeUnit.HOURS) // 2小时后过期
.build());
// 结果示例: https://play.min.io/my-bucketname/my-objectname?X-Amz-...
// 生成 POST 表单数据(用于前端直接上传)
PostPolicy policy = new PostPolicy("my-bucketname", ZonedDateTime.now().plusDays(7));
policy.addEqualsCondition("key", "my-objectname");
policy.addStartsWithCondition("Content-Type", "image/"); // 限制只能传图片
Map<String, String> formData = minioClient.getPresignedPostFormData(policy);
十二、核心概念十:SQL 查询对象(SelectObjectContent)
这是什么?
不需要下载整个文件,直接用 SQL 语句查询对象的内容。目前支持 CSV、JSON、Parquet 格式。
什么场景用?
- 大文件只取需要的行:一个 10GB 的 CSV 日志文件,只需要查某一天的记录,不用全下载
- 边缘计算:在存储端直接过滤,减少网络传输
java
SelectResponseStream stream = minioClient.selectObjectContent(
SelectObjectContentArgs.builder()
.bucket("my-bucketname")
.object("my-objectName")
.sqlExpression("select * from S3Object where s._1 = 'error'") // 只查错误日志
.inputSerialization(is) // 输入格式(CSV/JSON/Parquet)
.outputSerialization(os) // 输出格式
.requestProgress(true) // 是否返回进度
.build());
十三、基础对象操作
上传
java
// 方式1:上传文件
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket("my-bucketname").object("my-objectname")
.filename("local-file.pdf").build());
// 方式2:上传流(适合内存中的数据,如 base64 解码后的 bytes)
minioClient.putObject(
PutObjectArgs.builder()
.bucket("my-bucketname").object("my-objectname")
.stream(inputStream, fileSize, -1)
.contentType("application/pdf").build());
// 方式3:批量上传(通过 TAR 打包一次请求上传多个小文件)
minioClient.uploadSnowballObjects(
UploadSnowballObjectsArgs.builder().bucket("my-bucketname").objects(objects).build());
下载
java
// 方式1:下载到本地文件
minioClient.downloadObject(
DownloadObjectArgs.builder()
.bucket("my-bucketname").object("my-objectname")
.filename("local-file.pdf").build());
// 方式2:获取流(适合不落盘直接处理,如图片处理、流式转发)
try (InputStream stream = minioClient.getObject(
GetObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build())) {
// 边读边处理,比如直接返回给 HTTP Response
}
查看元数据(不下载内容)
java
ObjectStat stat = minioClient.statObject(
StatObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build());
System.out.println("大小: " + stat.size());
System.out.println("内容类型: " + stat.contentType());
System.out.println("最后修改: " + stat.lastModified());
复制
java
// 在 MinIO 服务端直接复制(不需要下载再上传,很快)
minioClient.copyObject(
CopyObjectArgs.builder()
.bucket("目标桶").object("目标对象名")
.source(CopySource.builder()
.bucket("源桶").object("源对象名").build())
.build());
组合多个对象
java
// 把多个文件在服务端拼接成一个(适合大文件分片上传后合并)
List<ComposeSource> sources = new ArrayList<>();
sources.add(ComposeSource.builder().bucket("my-bucket").object("part-1").build());
sources.add(ComposeSource.builder().bucket("my-bucket").object("part-2").build());
minioClient.composeObject(
ComposeObjectArgs.builder()
.bucket("my-bucket").object("merged-file").sources(sources).build());
删除
java
// 删一个
minioClient.removeObject(
RemoveObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build());
// 批量删
List<DeleteObject> objects = List.of(new DeleteObject("file1"), new DeleteObject("file2"));
Iterable<Result<DeleteError>> results = minioClient.removeObjects(
RemoveObjectsArgs.builder().bucket("my-bucketname").objects(objects).build());
// 遍历查看哪些删除失败了
for (Result<DeleteError> result : results) {
DeleteError error = result.get();
if (error != null) {
System.out.println("删除失败: " + error.objectName());
}
}
十四、完整方法速查
| 分类 | 方法 | 功能 |
|---|---|---|
| 桶-基础 | makeBucket |
创建桶 |
removeBucket |
删除空桶 | |
bucketExists |
检查桶是否存在 | |
listBuckets |
列出所有桶 | |
listObjects |
列出桶内对象 | |
| 桶-策略 | setBucketPolicy |
设置访问策略(JSON) |
getBucketPolicy |
获取当前策略 | |
deleteBucketPolicy |
删除策略 | |
| 桶-版本 | setBucketVersioning |
启用/禁用版本控制 |
getBucketVersioning |
查看版本控制状态 | |
| 桶-标签 | setBucketTags |
打标签 |
getBucketTags |
查看标签 | |
deleteBucketTags |
删除标签 | |
| 桶-加密 | setBucketEncryption |
设置加密 |
getBucketEncryption |
查看加密配置 | |
deleteBucketEncryption |
删除加密配置 | |
| 桶-生命周期 | setBucketLifecycle |
设置自动清理/降冷规则 |
getBucketLifecycle |
查看规则 | |
deleteBucketLifecycle |
删除规则 | |
| 桶-复制 | setBucketReplication |
设置跨区域复制规则 |
getBucketReplication |
查看规则 | |
deleteBucketReplication |
删除规则 | |
| 桶-通知 | setBucketNotification |
配置事件通知 |
getBucketNotification |
查看通知配置 | |
deleteBucketNotification |
删除通知配置 | |
listenBucketNotification |
代码中实时监听事件 | |
| 桶-对象锁 | setObjectLockConfiguration |
设置默认保留规则 |
getObjectLockConfiguration |
查看 | |
deleteObjectLockConfiguration |
删除 | |
| 对象-上传 | putObject |
上传(流) |
uploadObject |
上传(文件) | |
uploadSnowballObjects |
批量上传 | |
| 对象-下载 | getObject |
下载(流) |
downloadObject |
下载(文件) | |
| 对象-查询 | statObject |
查看元数据 |
selectObjectContent |
SQL 查询内容 | |
| 对象-操作 | copyObject |
拷贝 |
composeObject |
合并多个对象 | |
removeObject / removeObjects |
删除 | |
restoreObject |
解冻归档对象 | |
| 对象-标签 | getObjectTags / setObjectTags / deleteObjectTags |
对象标签 |
| 对象-锁定 | enableObjectLegalHold / disableObjectLegalHold |
合法保留 |
isObjectLegalHoldEnabled |
检查保留状态 | |
getObjectRetention / setObjectRetention |
保留期限配置 | |
| 预签名 | getPresignedObjectUrl |
生成临时下载/上传链接 |
getPresignedPostFormData |
生成 POST 上传表单 |