file - Dart - HTTPClient 下载文件到字符串
问题描述
在我目前正在开发的 Flutter/Dart 应用程序中,需要从我的服务器下载大文件。但是,我需要做的不是将文件存储在本地存储中,而是解析其内容并一次性使用它。我认为实现这一点的最佳方法是实现我自己的StreamConsumer
并覆盖相关方法。这是我到目前为止所做的
import 'dart:io';
import 'dart:async';
class Accumulator extends StreamConsumer<List<int>>
{
String text = '';
@override
Future<void> addStream(Stream<List<int>> s) async
{
print('Adding');
//print(s.length);
return;
}
@override
Future<dynamic> close() async
{
print('closed');
return Future.value(text);
}
}
Future<String> fileFetch() async
{
String url = 'https://file.io/bse4moAYc7gW';
final HttpClientRequest request = await HttpClient().getUrl(Uri.parse(url));
final HttpClientResponse response = await request.close();
return await response.pipe(Accumulator());
}
Future<void> simpleFetch() async
{
String url = 'https://file.io/bse4moAYc7gW';
final HttpClientRequest request = await HttpClient().getUrl(Uri.parse(url));
final HttpClientResponse response = await request.close();
await response.pipe(File('sample.txt').openWrite());
print('Simple done!!');
}
void main() async
{
print('Starting');
await simpleFetch();
String text = await fileFetch();
print('Finished! $text');
}
当我在 VSCode 中运行它时,这是我得到的输出
Starting
Simple done!! //the contents of the file at https://file.io/bse4moAYc7gW are duly saved in the file
sample.txt
Adding //clearly addStream is being called
Instance of 'Future<int>' //I had expected to see the length of the available data here
closed //close is clearly being called BUT
Finished! //back in main()
我对这里潜在问题的理解仍然相当有限。我的期望
- 我原以为我会用
addStream
积累正在下载的内容,直到 - 没有什么要下载的,此时
close
将调用该程序并且程序将显示exited
为什么addStream
显示instance of...
而不是可用内容的长度?尽管 VSCode 调试控制台确实会显示,exited
但这会在显示几秒钟后发生closed
。我认为这可能是不得不打电话的问题,super.close()
但不是这样。我在这里做错了什么?
解决方案
我本来打算删除这个问题,但决定在这里留下一个答案,以帮助其他尝试做类似事情的人。
需要注意的关键点是对的调用就是Accumulator.addStream
这样做的——它提供了一个流listened
,没有要读取的实际数据。你接下来要做的是这个
void whenData(List<int> data)
{
//you will typically get a sequence of one or more bytes here.
for(int value in data)
{
//accumulate the incoming data here
}
return;
}
function void whenDone()
{
//now that you have all the file data *accumulated* do what you like with it
}
@override
Future<void> addStream(Stream<List<int>> s) async
{
s.listen(whenData,onDone:whenDone);
//you can optionally ahandler for `onError`
}
推荐阅读
- ios - 将 APS 环境设置为开发时,推送通知不起作用
- java - 如何使用 LayoutInflater 动态添加 editText 和按钮并为它们设置唯一的 id?
- sql - 如何强制在 ssrs 报告中显示一周的开始
- html - 如何使文本显示在它的标签内?
- java - 不使用数组方法创建一副扑克牌
- java - cardview android中的可点击false无法工作
- angular - 如何在 Angular 7 中使用单个自定义属性指令绑定不同 HTML 元素的属性值?
- android - 如何在我的模拟器上为 Fireabase crashlytics 启用调试模式?
- ruby - 如何忽略参数化 Ruby 系统调用的输出
- typescript - 在打字稿中,如何定义通用函数的专用版本?