【问题标题】:Flutter - How to download a file from server using binary streamFlutter - 如何使用二进制流从服务器下载文件
【发布时间】:2018-09-12 10:36:19
【问题描述】:

我需要能够从私人服务器下载和显示图像。我发送的请求需要包含一个带有内容类型的标头和一个带有 sessionToken 和 userId 的正文。 服务器以内容类型 application/octet-stream 的二进制流响应。

这是我现在的代码:

 Future<Null> _downloadFile(String url, String userId, sessionToken) async {
    Map map = {'token': sessionToken, 'UserId': userId};

    try {
      var request = await httpClient.getUrl(Uri.parse(url));
      request.headers.set('content-type', 'application/json');
      request.add(utf8.encode(json.encode(map)));
      var response = await request.close();
      var bytes = await consolidateHttpClientResponseBytes(response);
      await _image.writeAsBytes(bytes);
      userImage(_image);
    }
    catch (value){
      print(value);
    }

  }

当我尝试阅读响应时,我收到此错误: HttpException:内容大小超过指定的 contentLength。 72 字节写入,而预期为 0。

我已经尝试无休止地在谷歌上搜索如何使用流从服务器下载文件,但我找不到任何东西。我需要的是类似于bitmap class in .NET 的东西,它可以接收流并将其转换为图像。

有人可以帮我吗?这将不胜感激。

【问题讨论】:

标签: dart flutter


【解决方案1】:

我可以用这段代码成功地做到这一点:

 void getImage(String url, String userId, sessionToken) async{
    var uri = Uri.parse(url);

    Map body = {'Session': sessionToken, 'UserId': userId};
    try {
      final response = await http.post(uri,
          headers: {"Content-Type": "application/json"},
          body: utf8.encode(json.encode(body)));

      if (response.contentLength == 0){
        return;
      }
      Directory tempDir = await getTemporaryDirectory();
      String tempPath = tempDir.path;
      File file = new File('$tempPath/$userId.png');
      await file.writeAsBytes(response.bodyBytes);
      displayImage(file);
    }
    catch (value) {
      print(value);
    }
  }

感谢您的帮助:)

【讨论】:

【解决方案2】:

这是一个相关示例,仅显示如何流式传输网页或文件的内容:

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

Future<void> main() async {
  final url = Uri.parse('https://google.com/');
  final client = http.Client();
  final request = http.Request('GET', url);
  final response = await client.send(request);
  final stream = response.stream;
  await for (var data in stream) {
    print(data.length);
  }
  client.close();
}

这是一个完整的示例,因此如果您将 http 包添加到您的 pubspec.yaml 文件中,您可以复制整个内容以进行测试。该示例打印了传入的每个数据块的大小。如果要将这些字节转换为字符串,可以使用stream.transform(utf8.decoder)

我正在使用上面的示例来了解流式传输的工作原理。更完整的解决方案需要处理错误并保存文件。

感谢 this answer 对此的帮助。

另见

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2013-06-13
    • 1970-01-01
    相关资源
    最近更新 更多