合作机构:阿里云 / 腾讯云 / 亚马逊云 / DreamHost / NameSilo / INWX / GODADDY / 百度统计
在日常开发中,我们经常需要处理文件上传、下载、存储与访问的场景,比如图片、视频、日志文件、模型数据集等。传统的文件系统难以满足高并发、分布式部署以及云原生化的需求,而 MinIO 作为一款高性能、轻量级、兼容 Amazon S3 协议的对象存储服务,正是为此而生。
本文将带你从零开始,通过 Docker 部署 MinIO 服务,并结合 Java SDK 实现文件的上传与访问。
docker pull minio/minio:RELEASE.2025-04-22T22-12-26Z1.
我们假设你希望访问端口为 9000(API)和 9001(Web 控制台),可以这样运行:
docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ -v /Users/zhangyong/docker/minio/data:/data \ -v /Users/zhangyong/docker/minio/config:/root/.minio \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=admin123456" \ minio/minio:RELEASE.2025-04-22T22-12-26Z \ server /data --console-address ":9001"1.2.3.4.5.6.7.8.9.10.
-p 9000:9000:MinIO API 服务端口
-p 9001:9001:Web 控制台端口
-v /Users/zhangyong/docker/minio/data:/data:映射数据目录
-v /Users/zhangyong/docker/minio/config:/root/.minio:保存配置
MINIO_ROOT_USER、MINIO_ROOT_PASSWORD:管理员账号密码
server /data --console-address ":9001":指定数据目录并启用控制台端口
控制台地址:http://localhost:9001
登录账号:admin
登录密码:admin123456
图片
在 MinIO(以及所有兼容 S3 的对象存储系统)中,桶(Bucket) 是最顶层的逻辑存储单元,可以理解为一个“命名空间”或“大文件夹”,它是所有对象(文件)的容器。
MinIO 不存在真正的目录结构,而是通过对象 key 的前缀来模拟目录层级。
例如,我们可以创建一个 bucket 叫 datasets ,数据集下面的文件对象如下:
datasets/ ├── mydataset1/ │ ├── train/image1.jpg │ └── train/image2.jpg └── mydataset2/ ├── data.csv └── labels.txt1.2.3.4.5.6.7.
虽然看起来像目录树,但实际上存储系统中只有对象:
datasets/mydataset1/train/image1.jpg datasets/mydataset1/train/image2.jpg datasets/mydataset2/data.csv datasets/mydataset2/labels.txt1.2.3.4.
MinIO 客户端(mc)或 SDK(Java/Python)在列举对象时,会自动把这些前缀识别为“目录”。
接下来,我们按照流程上传文件。
图片
图片
图片
图中,我们需要将访问策略从 Private 修改成 Public 。
图片
MinIO 地址:http://localhost:9000
桶名:datasets
对象路径:mydataset1/父与女.png
因为桶已经设置为 Public ,所以我们可以直接访问如下的链接即可:
图片
图片
图片
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.10</version> </dependency>1.2.3.4.5.
public class MinioUnitTest { public static void main(String[] args) { try { // 1. 初始化 MinIO 客户端 MinioClient minioClient = MinioClient.builder() .endpoint("http://localhost:9000") // MinIO 地址 // accessKey 和 secretKey .credentials("yHxFBiulXKsuhbg9nHqO", "qmsQU4JuWuwlr3ZgY4eMFbQ9LaTzzEHMV6T722kC") .build(); // 2. 文件信息 String bucketName = "datasets"; String objectName = "mydataset1/images/xiaoyuanjiang.webp"; // 上传路径(类似目录) String filePath = "/Users/zhangyong/Pictures/xiaoyuanjiang.webp"; // 本地文件路径 // 3. 上传文件(流式上传) try (InputStream in = new FileInputStream(filePath)) { minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(in, in.available(), -1) .contentType("image/png") // 可根据文件类型设置 .build() ); System.out.println("? 文件上传成功: " + objectName); } // 4. 拼接直链 URL(因为是 public bucket) String publicUrl = String.format("http://localhost:9000/%s/%s", bucketName, objectName); System.out.println("? 上传成功,直链地址:"); System.out.println(publicUrl); // // 4. 生成临时访问链接(可选) // String url = minioClient.getPresignedObjectUrl( // GetPresignedObjectUrlArgs.builder() // .method(Method.GET) // .bucket(bucketName) // .object(objectName) // .expiry(60 60) // 1小时有效 // .build() // ); // System.out.println("?? 临时访问地址: " + url); } catch (Exception e) { e.printStackTrace(); } } }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.
图片
TOP