dart - 如何在 flutter 的http.MultipartRequest请求上上传文件时获取进度事件

标签 dart flutter dart-http

我正在使用 package:http 中的 MultipartRequest 上传文件。我正在成功上传文件,但我想获取正在上传的文件的进度。我怎样才能做到这一点?我当前的代码看起来像这样

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;
}

我搜索了解决方案,找到了this .和this帖子在某种程度上与我想要实现的不相似,因为他使用不同的客户端进行请求。

也许我没有在正确的道路上寻找。 感谢您的帮助。

最佳答案

这是我的看法:

// multipart_request.dart

import 'dart:async';

import 'package:http/http.dart' as http;

class MultipartRequest extends http.MultipartRequest {
  /// Creates a new [MultipartRequest].
  MultipartRequest(
    String method,
    Uri url, {
    this.onProgress,
  }) : super(method, url);

  final void Function(int bytes, int totalBytes) onProgress;

  /// Freezes all mutable fields and returns a single-subscription [ByteStream]
  /// that will emit the request body.
  http.ByteStream finalize() {
    final byteStream = super.finalize();
    if (onProgress == null) return byteStream;

    final total = this.contentLength;
    int bytes = 0;

    final t = StreamTransformer.fromHandlers(
      handleData: (List<int> data, EventSink<List<int>> sink) {
        bytes += data.length;
        onProgress(bytes, total);
        if(total >= bytes) {
           sink.add(data);
        }
      },
    );
    final stream = byteStream.transform(t);
    return http.ByteStream(stream);
  }
}

用法:

import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart' show MediaType;

import 'multipart_request.dart';

final uri = 'https://...';
final request = MultipartRequest(
  'POST',
  uri,
  onProgress: (int bytes, int total) {
    final progress = bytes / total;
    print('progress: $progress ($bytes/$total)');
  },
);

request.headers['HeaderKey'] = 'header_value';
request.fields['form_key'] = 'form_value';
request.files.add(
  await http.MultipartFile.fromPath(
    'field_name',
    'path/to/file',
    contentType: MediaType('image', 'jpeg'),
  ),
);

final streamedResponse = await request.send();

关于dart - 如何在 flutter 的http.MultipartRequest请求上上传文件时获取进度事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53727911/

相关文章:

dart - 在 Dart 中向服务器发出多个独立请求的最佳方式

dart - 在Dart中获取元素索引

flutter - 如何在不使用 border-radius 的情况下创建弯曲的小部件

flutter - 位置小部件全宽

dart - 仅从 firestore 返回对象列表一次,而不是流。在 flutter 中

webview - WebView 关闭后,来自 Youtube 嵌入式视频的音频继续播放 - Flutter

flutter - 如何使用 StreamBuilder 管理 block 抛出的异常?

dart - polymer Dart 输入绑定(bind) int 属性

Angular 2根据模型在 View 中嵌入子组件

dart - 无法使用 Flutter 调用 Localhost,将随机端口分配给 HTTP GET 调用