I'm trying to make a progress bar indicator for a downloading file, but if I add a listener to the StreamedResponse
, the piping works, but does to not finish its future.
final client = new http.Client();
http.StreamedResponse response = await client.send(http.Request("GET", Uri.parse('someurl')));
var received = 0;
var length = response.contentLength;
//if I remove this listener, the await below gets completed
var listen = response.stream.listen((List<int> bytes) {
received += bytes.length;
print("${(received / length) * 100} %");
});
var sink = downloadFile.openWrite();
await response.stream.pipe(sink);
listen.cancel();
sink.close();
On github they already advised someone that it was supposed to work, but on StreamedResponse docs stays that This should always be a single-subscription stream.
. So, adding a listener to calculate the percentage seems to bugs StreamedResponse
pipe in someway. Any idea on how to get this to work?
@pskink comment let me to this solution that works for every type of sink
you are using.
var length = response.contentLength;
var received = 0;
var sink = downloadFile.openWrite();
await response.stream.map((s) {
received += s.length;
print("${(received / length) * 100} %");
return s;
}).pipe(sink);
another way to accomplish this, if you are writing into a file, is to watch file length
var length = response.contentLength;
var sink = downloadFile.openWrite();
Future.doWhile(() async {
var received = await downloadFile.length();
print("${(received / length) * 100} %");
return received != length;
});
await response.stream.pipe(sink);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With