【发布时间】:2020-12-04 03:09:49
【问题描述】:
我正在开发一个将图像上传到 Amazon S3 存储桶 的应用程序,而不仅仅是显示 Spinner,我会很高兴能够获得关于该上传状态的进度。
我正在使用 MultipartRequest 从 Package:http 上传文件。我正在成功上传文件,但我想获取正在上传的文件的进度。我怎样才能做到这一点?我当前的代码看起来像这样。
static Future<bool> uploadFile({@required userId, @required albumId, @required data, @required fileName}) async{
const _accessKeyId = 'AKIAVV**********';
const _secretKeyId = 'iyBmdn6v***************************';
const _region = 'us-east-1';
const _s3Endpoint = 'https://myalbums-content.s3.amazonaws.com';
final file = data;
var stream = new http.ByteStream(DelegatingStream.typed(file.openRead()));
final length = await file.length();
final uri = Uri.parse(_s3Endpoint);
final req = http.MultipartRequest("POST", uri);
var multipartFile = http.MultipartFile('file', stream, length,
contentType: new MediaType('image','JPG'));
final policy = Policy.fromS3PresignedPost(userId.toString() +'/'+ albumId.toString() +'/'+ fileName,
'myalbums-content', _accessKeyId, 15, length, region: _region);
final key = SigV4.calculateSigningKey(_secretKeyId, policy.datetime, _region, 's3');
final signature = SigV4.calculateSignature(key, policy.encode());
req.files.add(multipartFile);
req.fields['key'] = policy.key;
req.fields['acl'] = 'public-read';
req.fields['X-Amz-Credential'] = policy.credential;
req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
req.fields['X-Amz-Date'] = policy.datetime;
req.fields['Policy'] = policy.encode();
req.fields['X-Amz-Signature'] = signature;
try {
final res = await req.send();
if(res.statusCode == 204){
return true;
} else {
return false;
}
} catch (e) {
print('Network issue: '+e.toString());
return false;
}
}
提前谢谢你。
【问题讨论】:
-
send() 是未来。只需将 FutureBuilder 与 Send 一起使用,因为它是 Future
-
@Kent 那行不通。进度条会瞬间从 0 到 100,因为它只有两个状态,未来未完成和未来完成。没有任何方法可以获取传输的字节数与总字节数或请求的进度,没有办法做到这一点。
-
@WilsonWilson 嗯,它返回一个流。所以至少在下载时应该是可能的。我承认我没试过。但是流的全部意义在于获取块中的数据,而不仅仅是在完成之后。
-
@Kent 我同意,下载时很有可能。但是 OP 返回的是 Future
,而不是 Stream。所以如果他想得到进度,他需要返回一个Stream。我刚刚用 Github 上的一个例子回答了这个问题,这个例子准确地展示了它是如何完成的。