У меня есть следующий код для загрузки файла.
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
. Когда я загружаю файл размером ~ 10 МБ, индикатор выполнения перескакивает с 0% на 100% в течение секунды, а затем ждет пару секунд (в зависимости от размера файла), прежде чем продолжить выполнение остальной части кода. Мне это кажется странным, потому что я ожидаю, что индикатор выполнения будет постепенно увеличивать свой прогресс.
Ниже вы можете найти результаты печати из моего примера с файлом размером ~ 10 МБ.
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%. Я могу представить, как вы думаете, что это просто быстрый inte rnet. Но я пробовал Wi-Fi, 4G, 3G, и все они показывают одну и ту же проблему. Я нажимаю кнопку загрузки, она начинается с 0%, она переходит на 100%, а затем мне нужно подождать некоторое время (в зависимости от размера файла) для загрузки в fini sh.
Есть ли способ чтобы получить больше onSendProgress
обратных вызовов, запущенных во время загрузки, или как-то отложить загрузку, чтобы я мог добиться плавного процесса загрузки?
EDIT:
Я пробовал следующее с Пакет 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 от сервера. Поэтому я не думаю, что это особая проблема c DIO.
Я думаю, что похоже, что на самом деле это не показывает прогресс загрузки, а скорее прогресс чтения файла в поток на стороне клиента. . Затем поток загружается на сервер, и это то, чего вы ждете (конечно, в зависимости от размера файла), даже если прогресс показывает 100%.