前言
在移动开发中,我们常常会遇到需要在App中处理文件上传和下载的需求。Minio是一个开源的对象存储服务,它兼容Amazon S3云存储服务接口,可以用于存储大规模非结构化的数据。
开始之前
在pubspec.yaml文件中添加minio_new库的依赖:
dependencies:
minio_new: ^1.0.2
运行flutter pub get命令来获取依赖。可去pub上看 minio_new 最新版本。
初始化Minio客户端
需要先创建一个Minio客户端的实例。这个实例需要配置Minio服务器的连接信息,包括服务器的URL、端口号、访问密钥和密钥等。
var minio = Minio(
endPoint: 'your-minio-server.com',
port: 9000,
useSSL: false,
accessKey: 'your-access-key',
secretKey: 'your-secret-key',
);
参数介绍:
useSSL
:指定是否使用 SSL 连接。如果设置为 true,则使用 HTTPS 协议进行连接;如果设置为 false,则使用 HTTP 协议。
endPoint
:指定 MinIO 服务器的终端节点(Endpoint)。这是 MinIO 服务器的主机名或 IP 地址。
port:指定连接 MinIO 服务器的端口号。
accessKey
:指定用于身份验证的 MinIO 服务器的访问密钥。这是访问 MinIO 存储桶和对象所需的身份验证凭据之一,就是账号。
secretKey
:指定用于身份验证的 MinIO 服务器的秘密密钥。与访问密钥一同用于身份验证,就是密码。
创建桶(Bucket)
在Minio中,桶(Bucket)是一种用于组织和存储对象的容器。类似于文件系统中的文件夹,桶在Minio中用于对对象进行逻辑分组和管理。每个桶都具有唯一的名称,并且可以在Minio服务器上创建多个桶。
桶的命名规则:只能包含小写字母、数字和连字符(-),并且长度必须在3到63个字符之间。桶的名称在Minio服务器上必须是唯一的。
Future<void> createBucket(String bucketName) {
minio.makeBucket(bucketName);
//设置桶的公用权限,这样外界才能通过链接访问
return minio.setBucketPolicy(bucketName, {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
//一个可选参数,表示这个策略的 ID,可以随意填写。
"Effect": "Allow",
//表示策略的效果,如果希望所有人都可以读取,那么这里就填写 'Allow'。
"Principal": "*",
//表示策略的主体,如果希望所有人都可以读取,那么这里就填写 '*'。
"Action": ["s3:GetObject"],
//一个数组,表示允许的操作,如果希望所有人都可以读取,那么就填写 ['s3:GetObject']。
"Resource": ["arn:aws:s3:::$bucketName/*"]
//一个数组,表示策略的资源,如果希望所有人都可以读取桶中的所有对象,那么就填写 ['arn:aws:s3:::your_bucket/*']。
}
]
});
}
因为无论是上传还是下载文件都是基于桶进行操作的,所以初始化之后,在上传文件之前需要先创建桶,可以通过minio.bucketExists
事先来判断桶是否存在。
如果不设置桶的权限的话,也就是不调用上面minio.setBucketPolicy
方法,默认创建的桶是私有的,外界不能通过链接访问相关文件,出了调用minio.setBucketPolicy
设置权限外,也可以在Minio后台设置桶的权限,如下图:
上传文件
///上传文件
Future<String> uploadFile(String filename, String filePath) async {
minio.fPutObject(bucketName, filename, filePath);
//返回上传文件的完整访问路径
return getUrl(filename);
}
bucketName
:要上传到哪个桶就写哪个桶名。
filename
: 文件名,如:a.png。
filePath
: 要上传文件的路径。
下载文件同理。
完整代码
minio.dart
import 'dart:async';
import 'dart:io';
import 'package:ecology/utils/log_util.dart';
import 'package:ecology/utils/toast.dart';
import 'package:minio_new/io.dart';
import 'package:minio_new/minio.dart';
import 'package:minio_new/models.dart';
import 'package:path/path.dart' show dirname;
import 'package:path_provider/path_provider.dart';
// ignore: unused_import
import 'package:rxdart/rxdart.dart';
class Prefix {
bool isPrefix;
String key;
String prefix; //使用前缀可以帮助你更好地组织和管理对象,避免冲突和重复,并方便批量操作,不使用传''
Prefix({
required this.key, required this.prefix, required this