【minio】#4 | MinIO API 文件操作 一、文件上传PutObject / FPutObjectMinIO 上传特性文件超过 128MB 自动分片传输单文件上限 5TB。 模拟文件夹原理MinIO 本身没有文件夹概念通过 ObjectKey 前缀模拟目录如0114/ssh隧道命令.jpg。 访问地址拼接规则endPoint /桶名 /ObjectKey1. FPutObject直接传入本地文件路径上传适合读取服务器本地磁盘文件上传。func uploadFile1() { info, err : client.FPutObject(context.Background(), demo1, ssh隧道命令.jpg, ssh隧道命令.jpg, minio.PutObjectOptions{}) if err ! nil { fmt.Println(err) return } byteData, _ : json.Marshal(info) fmt.Println(string(byteData)) } func main() { uploadFile1() }2. PutObject传入文件流上传本地文件流可以携带自定义元数据UserMetadata用来存储 userId、客户端 IP 等业务信息。func uploadFile2() { file, _ : os.Open(ssh隧道命令.jpg) info, _ : file.Stat() data, err : client.PutObject(context.Background(), demo1, 0114/ssh隧道命令.jpg, file, info.Size(), minio.PutObjectOptions{ UserMetadata: map[string]string{ userId: 1, userIp: 2.5.21.22, }, }) if err ! nil { fmt.Println(err) return } }3. Gin Web 端 IO 流式上传前端表单文件推荐业务使用场景接收前端 form 表单上传文件不落地临时文件直接流转 MinIOfunc uploadView(c *gin.Context) { fileHeader, _ : c.FormFile(file) reader, err : fileHeader.Open() if err ! nil { log.Println(err) return } defer reader.Close() // 必须关闭流防止句柄泄漏 objectSize : fileHeader.Size uploadInfo, err : client.PutObject(context.Background(), fengfeng, fileHeader.Filename, reader, objectSize, minio.PutObjectOptions{ContentType: application/octet-stream}) if err ! nil { fmt.Println(err) return } fmt.Println(上传成功上传文件信息, uploadInfo) }业务完整版返回可访问地址 自定义元数据// Web上传完整版携带用户元数据返回访问链接 file, _ : fileHeader.Open() data, err : client.PutObject(context.Background(), demo1, uploads/fileHeader.Filename, file, fileHeader.Size, minio.PutObjectOptions{ UserMetadata: map[string]string{ userId: 1, userIp: c.ClientIP(), }, }) if err ! nil { fmt.Println(err) return } byteData, _ : json.Marshal(data) fmt.Println(string(byteData)) c.JSON(200, gin.H{data: fmt.Sprintf(http://%s/%s/%s, endPoint, data.Bucket, data.Key)})二、列出桶内文件 ListObjects作用遍历桶内对象支持前缀过滤、递归遍历子目录、读取自定义元数据。func fileList() { ch : client.ListObjects(context.Background(), demo1, minio.ListObjectsOptions{ Recursive: true, // true递归遍历所有子目录 Prefix: uploads,// 只匹配前缀uploads的对象筛选uploads目录 WithMetadata: true, // 开启才能读取UserMetadata自定义元数据 }) for info : range ch { fmt.Println(info.Key, info.LastModified, info.UserMetadata) } }参数说明Recursivetrue递归扫描 Prefix 下全部文件false 仅一级目录Prefix对象 key 前缀模拟文件夹筛选WithMetadata需要读取上传时自定义 UserMetadata 时开启三、文件下载两种方案1. FGetObject直接下载保存到本地磁盘直接将 MinIO 对象落地成本地文件代码最简适合服务端保存文件。// 整个文件下载和保存到指定目录适合文件下载如下载pdf文件 err : client.FGetObject(context.Background(), fengfeng, 1.md, 1.md, minio.GetObjectOptions{}) if err ! nil { fmt.Println(err) return } fmt.Println(成功)2. GetObject获取 io.Reader 文件流推荐 Web 前端下载返回对象流可以写入本地或者直接流式返回给浏览器不需要落地文件⚠️ 重要object必须 defer 关闭否则连接泄漏// 下载文件对象返回io.Reader流 object, err : client.GetObject(context.Background(), fengfeng, 1.md, minio.GetObjectOptions{}) if err ! nil { fmt.Println(err) return } file, _ : os.Create(x.md) defer file.Close() defer object.Close() io.Copy(file, object)四、删除文件 RemoveObject作用根据桶名 ObjectKey 删除指定单个文件。删除后不可恢复没有回收站默认func delFile() { bucketName : fengfeng objectKey : 1.md err : client.RemoveObject(context.Background(), bucketName, objectKey) if err ! nil { fmt.Println(删除失败, err) return } fmt.Println(文件删除成功) }Gin 接口版本Web 接口删除文件func delFileView(c *gin.Context) { bucketName : fengfeng objectKey : c.Query(key) err : client.RemoveObject(context.Background(), bucketName, objectKey) if err ! nil { c.JSON(500, gin.H{msg: 删除失败, err: err.Error()}) return } c.JSON(200, gin.H{msg: 删除成功}) }补充批量删除使用RemoveObjects适合一次性删除多个对象。核心知识点总结MinIO无真实文件夹依靠 ObjectKey 前缀模拟目录如uploads/test.jpg上传128MB 自动分片单文件上限 5TBPutObject 支持 UserMetadata存储业务自定义信息userId、ip 等ListObjects 查询文件Recursive 递归、Prefix 前缀筛选WithMetadata 读取自定义元数据下载FGetObject直接保存本地文件GetObject拿到 io 流灵活转发给前端大文件推荐流式IO 流操作切记defer reader.Close()防止文件句柄 / 连接池泄漏RemoveObject删除对象删除后默认不可恢复业务谨慎使用