传统模式云存储
CloudBase Flutter SDK 在传统模式下通过 app.storage.from() 操作环境内置云存储。上传时传入相对路径,成功后返回完整 fileID。下载、删除、签名 URL 使用完整 fileID。
传统模式与 PG 模式 API 的关键差异:
| 维度 | 传统模式 | PG 模式 |
|---|---|---|
| 入口 | app.storage.from() | app.storage.fromBucket(bucketId) |
| 路径参数 | 上传、复制、移动用相对路径;下载、删除、签名 URL 用 cloud:// fileID | Bucket 内对象名,如 user-123/avatar.png |
| 权限模型 | 内置权限 + JSON 安全规则 | PostgreSQL RLS(Row Level Security,行级安全策略) |
| 覆盖默认值 | upsert 默认 true | upsert 默认 false |
| Bucket 管理 | 不支持 | 支持 createBucket / listBuckets 等 |
| 文件列表 | 不支持 | 支持 list() |
| 公开 URL | 不支持 | getPublicUrl() 本地拼接 |
| 对象信息 | 不支持 | 支持 info() / exists() |
详见:PG 模式云存储
初始化
final app = await CloudBase.init(
env: 'your-env-id',
accessKey: 'your-access-key',
);
final storage = app.storage.from();
upload
Future<StorageResponse<StorageUploadResult>> storage.upload(
String path,
List<int> fileData, {
StorageUploadOptions? options,
})
上传文件到云存储。该方法会先获取上传信息,再上传文件到 COS,最后返回 fileID。
参数
云存储相对路径,如 `images/photo.jpg`。
文件字节数据。
上传选项。
返回
返回数据
错误信息。
示例
- 上传文件
- 上传选项
final app = await CloudBase.init(
env: 'your-env-id',
accessKey: 'your-access-key',
);
final storage = app.storage.from();
// 选择图片并上传
Future<void> uploadImage() async {
final picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image == null) return;
final fileBytes = await image.readAsBytes();
final result = await storage.upload(
'images/${image.name}',
fileBytes,
options: StorageUploadOptions(
contentType: 'image/jpeg',
cacheControl: 'max-age=3600',
),
);
if (result.isSuccess) {
print('上传成功: ${result.data?.id}');
print('文件路径: ${result.data?.path}');
} else {
print('上传失败: ${result.error?.message}');
}
}
// 不覆盖已存在的文件
final result = await storage.upload(
'images/photo.jpg',
fileBytes,
options: StorageUploadOptions(upsert: false),
);
// 自定义元数据
final result = await storage.upload(
'images/photo.jpg',
fileBytes,
options: StorageUploadOptions(
metadata: {'userId': '123', 'category': 'avatar'},
),
);
getUploadInfo
Future<StorageResponse<List<StorageUploadInfo>>> storage.getUploadInfo(
List<String> paths,
)
获取文件上传信息。返回上传 URL 等信息,用于客户端直接上传文件到 COS。
参数
文件路径列表(云存储相对路径)。
返回
上传信息列表。
错误信息。
示例
- 获取上传信息
final result = await storage.getUploadInfo([
'images/photo.jpg',
'documents/report.pdf',
]);
if (result.isSuccess) {
for (final info in result.data!) {
print('路径: ${info.path}');
print('上传链接: ${info.uploadUrl}');
print('文件ID: ${info.fileId}');
}
}
getDownloadUrls
Future<StorageResponse<List<StorageDownloadInfo>>> storage.getDownloadUrls(
List<String> fileIds, {
int? expiresIn,
})
获取文件下载链接。
参数
文件 ID 列表(完整 cloudObjectId,如 `cloud://envId.xxx/path/file.jpg`)。
临时链接有效期,单位秒。传入后作为 `maxAge` 下发。
返回
下载信息列表。
错误信息。
示例
- 获取下载链接
final result = await storage.getDownloadUrls([
'cloud://envId.xxx/images/photo.jpg',
'cloud://envId.xxx/documents/report.pdf',
]);
if (result.isSuccess) {
for (final info in result.data!) {
if (info.isSuccess) {
print('下载链接: ${info.downloadUrl}');
} else {
print('获取失败: ${info.message}');
}
}
}
createSignedUrl
Future<StorageResponse<String>> storage.createSignedUrl(
String fileId,
int expiresIn,
)
创建签名 URL(临时访问链接)。
参数
完整 fileID。
有效期(秒)。
返回
签名 URL。
错误信息。
示例
- 创建签名 URL
final result = await storage.createSignedUrl(
'cloud://envId.xxx/images/photo.jpg',
3600, // 1小时有效期
);
if (result.isSuccess) {
print('签名 URL: ${result.data}');
}
createSignedUrls
Future<StorageResponse<List<StorageDownloadInfo>>> storage.createSignedUrls(
List<String> fileIds,
int expiresIn,
)
批量创建签名 URL。
参数
完整 fileID 列表。
有效期(秒)。
返回
下载信息列表。
错误信息。
示例
- 批量创建签名 URL
final result = await storage.createSignedUrls(
[
'cloud://envId.xxx/images/photo1.jpg',
'cloud://envId.xxx/images/photo2.jpg',
],
3600,
);
if (result.isSuccess) {
for (final info in result.data!) {
print('${info.fileId}: ${info.downloadUrl}');
}
}
remove
Future<StorageResponse<List<StorageDeleteResult>>> storage.remove(
List<String> fileIds,
)
删除文件。
参数
要删除的文件 ID 列表(完整 fileID)。
返回
删除结果列表。
错误信息。
示例
- 删除文件
final result = await storage.remove([
'cloud://envId.xxx/images/photo.jpg',
'cloud://envId.xxx/documents/report.pdf',
]);
if (result.isSuccess) {
for (final item in result.data!) {
if (item.isSuccess) {
print('删除成功: ${item.fileId}');
} else {
print('删除失败: ${item.fileId} - ${item.message}');
}
}
}
copy
Future<StorageResponse<StorageCopyResult>> storage.copy(
String fromPath,
String toPath, {
bool overwrite = true,
})
复制文件。
参数
源文件路径(相对路径)。
目标文件路径(相对路径)。
目标已存在时是否覆盖,默认 `true`。
返回
复制结果。
错误信息。
示例
- 复制文件
final result = await storage.copy(
'images/photo.jpg',
'images/backup/photo.jpg',
);
if (result.isSuccess) {
print('复制成功: ${result.data?.cloudObjectId}');
} else {
print('复制失败: ${result.error?.message}');
}
copyBatch
Future<StorageResponse<List<StorageCopyResult>>> storage.copyBatch(
List<Map<String, dynamic>> items,
)
批量复制文件。
参数
复制项列表。每项包含 `srcPath`、`dstPath`,也接受 `from`、`to` 作为别名。可选 `overwrite`(目标已存在时是否覆盖,默认 true)、`removeOriginal`(复制后是否删除源文件,默认 false)。
返回
复制结果列表。
错误信息。
示例
- 批量复制文件
final result = await storage.copyBatch([
{'srcPath': 'images/photo1.jpg', 'dstPath': 'backup/photo1.jpg'},
{'srcPath': 'images/photo2.jpg', 'dstPath': 'backup/photo2.jpg'},
]);
if (result.isSuccess) {
for (final item in result.data!) {
if (item.isSuccess) {
print('复制成功: ${item.cloudObjectId}');
}
}
}
move
Future<StorageResponse<StorageCopyResult>> storage.move(
String fromPath,
String toPath, {
bool overwrite = true,
})
移动文件(通过 copy + removeOriginal 实现)。
参数
源文件路径(相对路径)。
目标文件路径(相对路径)。
目标已存在时是否覆盖,默认 `true`。
返回
移动结果。
错误信息。
示例
- 移动文件
final result = await storage.move(
'images/old.jpg',
'images/new.jpg',
);
if (result.isSuccess) {
print('移动成功: ${result.data?.cloudObjectId}');
} else {
print('移动失败: ${result.error?.message}');
}
存储相关类型
StorageUploadOptions
上传选项:
| 参数 | 类型 | 说明 |
|---|---|---|
cacheControl | String? | 缓存控制,如 max-age=3600 |
contentType | String? | 文件 MIME 类型,如 image/jpeg |
metadata | Map<String, dynamic>? | 自定义元数据 |
upsert | bool | 是否覆盖已存在的文件,默认 true |
StorageUploadResult
上传结果:
| 参数 | 类型 | 说明 |
|---|---|---|
id | String? | CloudBase fileID |
path | String? | 上传路径 |
fullPath | String? | 文件完整路径 |
StorageUploadInfo
上传信息:
| 参数 | 类型 | 说明 |
|---|---|---|
path | String? | 文件路径 |
uploadUrl | String? | 上传链接 |
token | String? | 上传 token |
authorization | String? | 上传鉴权 |
fileId | String? | 文件 ID |
cosFileId | String? | COS 文件 ID |
code | String? | 错误码 |
message | String? | 错误信息 |
StorageDownloadInfo
下载信息:
| 参数 | 类型 | 说明 |
|---|---|---|
fileId | String? | 文件 ID |
downloadUrl | String? | 下载链接 |
code | String? | 错误码(部分失败时) |
message | String? | 错误信息(部分失败时) |
StorageDeleteResult
删除结果:
| 参数 | 类型 | 说明 |
|---|---|---|
fileId | String? | 文件 ID |
code | String? | 错误码(部分失败时) |
message | String? | 错误信息(部分失败时) |
StorageCopyResult
复制结果:
| 参数 | 类型 | 说明 |
|---|---|---|
cloudObjectId | String? | 复制后对象的云端文件 ID |
code | String? | 错误码(部分失败时) |
message | String? | 错误信息(部分失败时) |
StorageResponse<T>
存储响应:
| 参数 | 类型 | 说明 |
|---|---|---|
data | T? | 响应数据 |
error | StorageError? | 错误信息 |
StorageError
存储错误:
| 参数 | 类型 | 说明 |
|---|---|---|
code | String? | 错误码 |
message | String? | 错误信息 |
requestId | String? | 请求 ID |