我有下面的代码来上传一个文件。
var client = new dio.Dio();
await client.put(
url,
data: formData,
options: dio.Options(
headers: headers,
),
onSendProgress: (int sent, int total) {
final progress = sent / total;
print('progress: $progress ($sent/$total)');
},
);
上传文件没问题。问题是,我有一个视图,它有一个圆形进度条,当onSendProgress
被触发时,进度条会指示上载进度。当我上载一个约10MB的文件时,进度条会在一秒钟内从0%跳到100%,然后等待几秒钟(取决于文件大小),然后再继续其余的代码。这对我来说似乎很奇怪,因为我期望进度条逐渐增加进度。
下面您可以找到我的示例中的打印输出,文件大小为~10MB。
flutter: progress: 0.000003035281907563734 (29/9554302)
flutter: progress: 0.000013187776563897604 (126/9554302)
flutter: progress: 0.999996546058519 (9554269/9554302)
flutter: progress: 0.9999967553883057 (9554271/9554302)
flutter: progress: 1.0 (9554302/9554302)
这是一个更小的文件,但是回调的数量是一样的。
flutter: progress: 0.00001847214941293598 (29/1569931)
flutter: progress: 0.00008025830434585978 (126/1569931)
flutter: progress: 0.9999789799679094 (1569898/1569931)
flutter: progress: 0.9999802539092483 (1569900/1569931)
flutter: progress: 1.0 (1569931/1569931)
正如你所看到的,它从0%跳到100%。我可以想象你会想,这只是快速的互联网。但我试过Wifi,4G,3G,他们都显示同样的问题。我点击上传按钮,它从0%开始跳到100%,然后我必须等待一段时间(取决于文件大小)上传完成。
有没有办法在上传过程中触发更多的onSendProgress
回调,或者以某种方式延迟上传,这样我就可以获得一个平稳的上传过程?
编辑:
我对HTTP包尝试了以下方法
import 'dart:async';
import 'package:http/http.dart' as http;
class UploadRequest extends http.MultipartRequest {
final void Function(int bytes, int totalBytes) onProgress;
UploadRequest(
String method,
Uri url, {
this.onProgress,
}) : super(method, url);
http.ByteStream finalize() {
final byteStream = super.finalize();
if (onProgress == null) return byteStream;
final total = this.contentLength;
final t = StreamTransformer.fromHandlers(
handleData: (List<int> data, EventSink<List<int>> sink) {
onProgress(data.length, total);
sink.add(data);
},
);
final stream = byteStream.transform(t);
return http.ByteStream(stream);
}
}
触发器:
final request = UploadRequest(
'PUT',
Uri.parse(url),
onProgress: (int bytes, int total) {
print('progress: $progress ($sent/$total)');
},
);
request.headers.addAll(headers);
request.files.add(
http.MultipartFile.fromBytes(
'file',
attachment.file.buffer.asUint8List(),
filename: attachment.name,
contentType: MediaType.parse(attachment.contentType),
),
);
var response = await request.send();
但遗憾的是,这也有同样的问题。文件上传正常,但进度回调只被调用了几次。它立即达到100%,然后我必须等待一段时间(取决于文件大小)才能从服务器获得2xx响应。所以我不认为这是一个特定的DIO问题。
我认为它看起来并没有显示上传进度,而是显示了文件被读入流客户端的进度。然后流被上传到服务器,这就是你所等待的(当然取决于文件大小),即使进度显示为100%。
6条答案
按热度按时间fbcarpbf1#
这似乎是
dio
上的一个bug,我可以看到两种方法可以解决这个问题:1.只要在循环进度中添加一个数字,它就会显示
99%
(截断其余部分),这样用户就知道它还没有完成,因为100%
只会在你得到1.0
的结果时发生)。1.使用http软件包代替。
http
软件包作为StreamedRequest
,这将给予您能够更好地控制正在发送的内容,因此您可以在UI上反映这一点。sshcrbum2#
我找到了解决办法。
只需使用
file.openRead()
作为请求的data
参数,而PUT
是一个文件。对于
MultipartFile
可能可以使用MultipartFile(file.openRead(), file.lenthSync())
。但是我没有验证这一点,如果需要的话,有人可以尝试一下。进度回调现在很顺利。
ulydmbyx3#
我遇到了同样的问题。我尝试了几十种方法,但都没有效果。我不得不用MultipartFile.fromFile替换MultipartFile.fromBytes。它对我很有效。
xytpbqjk4#
你必须使用
formData
作为Map
而不是FormData.fromMap()
。你必须把
options
写成e7arh2l65#
在本例中非常简单
用法
g2ieeal76#
1.==使用以下函数工作:==
这些百分比,例如10%、20%、50%、75%等。
2.==使用以下函数不起作用:==
如您所见,它从0%跳至100%
例如:我使用await MultipartFile.fromFile(文件路径),onSendProgress工作正常。
onSendProgress正在工作。