Flutter对象存储插件minio的使用
Flutter对象存储插件minio的使用
MinIO Dart 简介
MinIO Dart 是一个非官方的 MinIO 客户端 SDK,它提供了简单的 API 来访问任何兼容 Amazon S3 的对象存储服务器。该 SDK 支持多种操作,包括桶(bucket)管理、对象管理、预签名 URL 创建等。
API 概览
Bucket operations | Object operations | Presigned operations | Bucket Policy & Notification operations |
---|---|---|---|
makeBucket | getObject | presignedUrl | getBucketNotification |
listBuckets | getPartialObject | presignedGetObject | setBucketNotification |
bucketExists | fGetObject | presignedPutObject | removeAllBucketNotification |
removeBucket | putObject | presignedPostPolicy | listenBucketNotification |
listObjects | fPutObject | getBucketPolicy | |
listObjectsV2 | copyObject | setBucketPolicy | |
listIncompleteUploads | statObject | ||
listAllObjects | removeObject | ||
listAllObjectsV2 | removeObjects | ||
removeIncompleteUpload |
使用方法
初始化 MinIO 客户端
final minio = Minio(
endPoint: 'play.min.io',
accessKey: 'Q3AM3UQ867SPQQA43P2F',
secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG',
);
对于 AWS S3 和其他兼容 S3 的服务提供商,可以类似地初始化客户端:
// AWS S3
final minio = Minio(
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
);
// Filebase
final minio = Minio(
endPoint: 's3.filebase.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
useSSL: true,
);
文件上传
import 'package:minio/io.dart';
import 'package:minio/minio.dart';
void main() async {
final minio = Minio(
endPoint: 'play.min.io',
accessKey: 'Q3AM3UQ867SPQQA43P2F',
secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG',
);
await minio.fPutObject('mybucket', 'myobject', 'path/to/file');
}
带进度的文件上传
import 'package:minio/minio.dart';
void main() async {
final minio = Minio(
endPoint: 'play.min.io',
accessKey: 'Q3AM3UQ867SPQQA43P2F',
secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG',
);
await minio.putObject(
'mybucket',
'myobject',
Stream<Uint8List>.value(Uint8List(1024)),
onProgress: (bytes) => print('$bytes uploaded'),
);
}
获取对象
import 'dart:io';
import 'package:minio/minio.dart';
void main() async {
final minio = Minio(
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
);
final stream = await minio.getObject('BUCKET-NAME', 'OBJECT-NAME');
// 获取对象长度
print(stream.contentLength);
// 将对象数据流写入文件
await stream.pipe(File('output.txt').openWrite());
}
示例代码
以下是一个完整的示例代码,展示了如何创建桶、上传文件、获取预签名 URL、复制对象、列出对象、获取对象元数据、删除对象和删除桶等操作。
import 'package:minio/io.dart';
import 'package:minio/minio.dart';
void main() async {
final minio = Minio(
endPoint: 'play.min.io',
accessKey: 'Q3AM3UQ867SPQQA43P2F',
secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG',
useSSL: true,
);
final bucket = '00test';
final object = 'custed.png';
final copy1 = 'custed.copy1.png';
final copy2 = 'custed.copy2.png';
if (!await minio.bucketExists(bucket)) {
await minio.makeBucket(bucket);
print('bucket $bucket created');
} else {
print('bucket $bucket already exists');
}
final poller = minio.listenBucketNotification(
bucket,
events: [
's3:ObjectCreated:*',
],
);
poller.stream.listen((event) {
print('--- event: ${event['eventName']}');
});
final region = await minio.getBucketRegion('00test');
print('--- object region:');
print(region);
final etag = await minio.fPutObject(bucket, object, 'example/$object');
print('--- etag:');
print(etag);
final url = await minio.presignedGetObject(bucket, object, expires: 1000);
print('--- presigned url:');
print(url);
final copyResult1 = await minio.copyObject(bucket, copy1, '$bucket/$object');
final copyResult2 = await minio.copyObject(bucket, copy2, '$bucket/$object');
print('--- copy1 etag:');
print(copyResult1.eTag);
print('--- copy2 etag:');
print(copyResult2.eTag);
await minio.fGetObject(bucket, object, 'example/$copy1');
print('--- copy1 downloaded');
await minio.listObjects(bucket).forEach((chunk) {
print('--- objects:');
for (var o in chunk.objects) {
print(o.key);
}
});
await minio.listObjectsV2(bucket).forEach((chunk) {
print('--- objects(v2):');
for (var o in chunk.objects) {
print(o.key);
}
});
final stat = await minio.statObject(bucket, object);
print('--- object stat:');
print(stat.etag);
print(stat.size);
print(stat.lastModified);
print(stat.metaData);
await minio.removeObject(bucket, object);
print('--- object removed');
await minio.removeObjects(bucket, [copy1, copy2]);
print('--- copy1, copy2 removed');
await minio.removeBucket(bucket);
print('--- bucket removed');
poller.stop();
}
特性和问题
请在 issue tracker 上提交功能请求和错误报告。欢迎贡献代码。
许可证
MIT License - 详情
希望这些信息对你有帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter对象存储插件minio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter对象存储插件minio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用MinIO对象存储插件的示例代码。这个示例将展示如何连接到MinIO服务器、创建存储桶、上传和下载文件。
首先,你需要在Flutter项目中添加minio
依赖。由于Flutter本身没有官方的MinIO插件,我们将使用Dart的HTTP客户端库与MinIO的REST API进行交互。以下步骤假设你已经有一个运行中的MinIO服务器,并且你有访问密钥和密钥对。
-
添加依赖: 在
pubspec.yaml
文件中添加http
依赖。dependencies: flutter: sdk: flutter http: ^0.13.3 # 请检查最新版本
-
连接到MinIO服务器:
下面是一个示例代码,展示如何连接到MinIO服务器、创建存储桶、上传和下载文件。
import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; class MinioClient { final String endpoint; final int port; final String accessKey; final String secretKey; MinioClient({ required this.endpoint, required this.port, required this.accessKey, required this.secretKey, }); String get authorizationHeader { var date = DateTime.now().toUtc().toHttpDate(); var stringToSign = 'PUT\n\n\n${date}\n/your-bucket-name\n'; var secretAccessKey = secretKey; var hmacSha256 = Hmac(sha256, utf8.encode(secretAccessKey)) .convert(utf8.encode(date)); var signature = base64.encode(hmacSha256.bytes); var authorization = 'AWS4-HMAC-SHA256 Credential=${accessKey}/${_getDateStamp()}/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=$signature'; return authorization; } String _getDateStamp() { var now = DateTime.now().toUtc(); return '${now.year}${now.month < 10 ? '0' : ''}${now.month}${now.day < 10 ? '0' : ''}${now.day}'; } Future<void> createBucket(String bucketName) async { var url = Uri.parse('http://$endpoint:$port/$bucketName'); var response = await http.put( url, headers: { 'Authorization': authorizationHeader, 'x-amz-content-sha256': 'UNSIGNED-PAYLOAD', 'x-amz-date': DateTime.now().toUtc().toHttpDate(), 'Host': '$endpoint:$port', }, ); if (response.statusCode != 200) { throw Exception('Failed to create bucket: ${response.statusCode}'); } } Future<void> uploadFile(String bucketName, File file, String objectName) async { var multipartFile = await http.MultipartFile.fromPath( 'file', file.path, contentType: MediaType('application', 'octet-stream'), ); var request = http.MultipartRequest('POST', Uri.parse('http://$endpoint:$port/$bucketName/$objectName')); request.headers.addAll({ 'Authorization': authorizationHeader, 'x-amz-content-sha256': 'UNSIGNED-PAYLOAD', 'x-amz-date': DateTime.now().toUtc().toHttpDate(), 'Host': '$endpoint:$port', }); request.files.add(multipartFile); var response = await request.send(); if (response.statusCode != 200) { throw Exception('Failed to upload file: ${response.statusCode}'); } } Future<void> downloadFile(String bucketName, String objectName, File outputFile) async { var url = Uri.parse('http://$endpoint:$port/$bucketName/$objectName'); var response = await http.get( url, headers: { 'Authorization': authorizationHeader, 'x-amz-date': DateTime.now().toUtc().toHttpDate(), 'Host': '$endpoint:$port', }, ); if (response.statusCode != 200) { throw Exception('Failed to download file: ${response.statusCode}'); } await outputFile.writeAsBytes(response.bodyBytes); } } void main() async { var minioClient = MinioClient( endpoint: 'your-minio-server-endpoint', port: 9000, accessKey: 'your-access-key', secretKey: 'your-secret-key', ); try { // 创建存储桶 await minioClient.createBucket('your-bucket-name'); print('Bucket created successfully'); // 上传文件 var file = File('path/to/your/file.txt'); await minioClient.uploadFile('your-bucket-name', file, 'file.txt'); print('File uploaded successfully'); // 下载文件 var outputFile = File('path/to/downloaded/file.txt'); await minioClient.downloadFile('your-bucket-name', 'file.txt', outputFile); print('File downloaded successfully'); } catch (e) { print('Error: $e'); } }
注意事项:
- 上面的代码示例仅用于说明如何与MinIO进行交互,并不包含所有错误处理和边缘情况。
authorizationHeader
的生成逻辑只是一个示例,实际的签名过程会更复杂,并且需要符合AWS V4签名规范。- 你可以使用MinIO官方提供的SDK(如Python SDK)生成签名,然后在Flutter中直接使用这些签名。
- 请确保在生产环境中使用HTTPS来保护你的通信。
希望这个示例代码对你有所帮助!