web-dev-qa-db-fra.com

Comment obtenir un événement de progression lors du téléchargement d'un fichier sur une requête http.MultipartRequest

Je télécharge un fichier en utilisant MultipartRequest à partir de package:http. Je télécharge le fichier avec succès, mais je souhaite connaître l'état d'avancement du fichier en cours de téléchargement. Comment puis-je y arriver? Mon code actuel ressemble à quelque chose comme ça

Future submitFile(var report, File file) async {
var uri = Uri.parse(endpoint + "v1/reports");
  var request = http.MultipartRequest("POST", uri);
  await addHeaders(request.headers);
  request.fields.addAll(Report.toMap(report));
  if (file != null)
    request.files.add(await http.MultipartFile.fromPath(
      'report_resource',
      file.path,
    ));

  String response = "";
  await (await request.send()).stream.forEach((message) {
    response = response + String.fromCharCodes(message);
  });
  return response;
}

J'ai cherché la solution, trouvé ceci . Et this post n’est pas similaire à ce que je veux réaliser, car il utilise un client différent pour la requête.

Peut-être que je ne cherche pas sur le bon chemin… .. L'aide est appréciée.

8
Aawaz Gyawali

Après avoir attendu environ une semaine. Je n'ai pas eu de réponse. C'est ainsi que j'ai développé moi-même un plugin pour obtenir ce comportement. Paquet lien .

Exemple d'utilisation:

var request = MultipartRequest();

request.addFile("image", imagePath);

Response response = request.send();

response.onError = () {
  print("Error");
};

response.onComplete = (response) {
  print(response);
};

response.progress.listen((int progress) {
  print("progress from response object " + progress.toString());
});

Remarque: ce package ne fonctionne que sur Android.

4
Aawaz Gyawali

Pouvez-vous essayer cette classe, car je ne l’ai pas encore testée? Dites-moi si quelque chose est imprimé dans votre console.

class MF extends http.MultipartRequest{
  MF(String method, Uri url) : super(method, url);
  @override
  Future<http.StreamedResponse> send() async {

    var client = new Client();
    int byteCount = 0;
    Stream<List<int>> onDone<T>(Stream<List<int>> stream, void onDone()) =>
        stream.transform(new StreamTransformer.fromHandlers(
            handleDone: (sink) {
              sink.close();
              onDone();
        },
          handleData: (data, sink) {
            byteCount += data.length;
            print(byteCount);
            sink.add(data);
          },
        ),
        );

    try {
      var response = await client.send(this);
      var stream = onDone(response.stream, client.close);
      return new StreamedResponse(new ByteStream(stream), response.statusCode,
          contentLength: response.contentLength,
          request: response.request,
          headers: response.headers,
          isRedirect: response.isRedirect,
          persistentConnection: response.persistentConnection,
          reasonPhrase: response.reasonPhrase);
    } catch (_) {
      client.close();
      rethrow;
    }
  }

}

USAGE: 

au lieu de var request = http.MultipartRequest("POST", uri);

utilisation:

var request = MF("POST", uri);
1
Saed Nabil

C'est très facile de faire cela avec dio package:

Response response;
String filePath="...";
//upload a video
response = await dio.post(
  "/upload",
  data: FormData.from({
    "file": UploadFileInfo(File(filePath), "bee.mp4"),
  }),
  onSendProgress: (received, total) {
    if (total != -1) {
      print((received / total * 100).toStringAsFixed(0) + "%");
    }
  },
);
0
wendu