如何等待 openRead 函数在一个文件上完成,然后再转到下一个文件?
Posted
技术标签:
【中文标题】如何等待 openRead 函数在一个文件上完成,然后再转到下一个文件?【英文标题】:How to wait for openRead function to complete on one file before moving on to the next? 【发布时间】:2019-10-18 11:10:41 【问题描述】:我正在尝试在 Dart 中按特定顺序加载多个文件。这些文件是经过修改的 GTFS(通用运输提要规范)类型,并且通过文件之间的“id”相互连接。因此,我试图一个一个地加载每个文件,但由于它们的大小很大,我使用 File 类的 openRead 方法使用 LineSplitter 转换器逐行流式传输它们。
它们是如何被加载的(开始是 openRead 方法的字节偏移)
Stream<List<int>> getFileStream(String fileName, int start) => File(fileName).openRead(start);
// Example Stream
Stream<List<int>> stops = getFileStream("stops.txt", start: 117);
Stream<List<int>> routes = getFileStream("routes.txt", start: 131);
// How the stream data is being read
stops
.transform(utf8.decoder)
.transform(LineSplitter())
.listen(
(String line)
List<String> values = line.split(',');
// Do stuff..
,
onDone: () ,
onError: (e) print(e.toString());
);
routes
.transform(utf8.decoder)
.transform(LineSplitter())
.listen(
(String line)
List<String> values = line.split(',');
// Do stuff..
// Error occurs here as well since the processing taking place here depends on the processing which takes place when the stops file is read
,
onDone: () ,
onError: (e) print(e.toString());
);
但是,由于我在同一个函数中加载了多个文件,并且它们都是带有侦听回调集的流,并且它们依赖于对它们之前的文件的处理才能完全完成,因此程序会产生错误,因为所有正在逐行读取文件,其他文件的处理尚未完成。
理想情况下,我想使用await for (String line in stops)
行或类似的东西,但是会产生以下我不知道如何解决的错误:
The type 'Stream<List<int>>' used in the 'for' loop must implement Stream with a type argument that can be assigned to 'String'.
即使我在await for
行之前对流进行了.transform
调用,此错误仍然会出现。
我还尝试将流的onDone
方法链接在一起,这些方法产生了令人讨厌的代码,但仍然无法正常工作(在函数中创建并添加到函数中的列表在返回时为空???)
最好使用await for
语法,因为这样可以生成更简洁的代码,但是我不想用异步、等待函数尤其是main()
函数污染整个函数树。
唯一有效的是使用来自 dart:async
的 Completer 类,但是为此需要链接 onDone
方法,并且代码几乎不可读。
我们将不胜感激任何有关 Futures 和 async/await 的帮助和指导。
【问题讨论】:
函数的返回类型是List<List<dynamic>>
,因为它是一个GTFS对象列表。
【参考方案1】:
你尝试过这样的事情吗?
await for (var line in stops
.transform(utf8.decoder)
.transform(LineSplitter()))
List<String> values = line.split(',');
// Do stuff..
// Error occurs here as well since the processing taking place here depends on the processing which takes place when the stops file is read
【讨论】:
谢谢!这非常有效。你知道为什么在单独的行上调用stops.transform(utf8.decoder).transform(LineSplitter())
然后await for (var line in stops)
不起作用吗? transform() 是修改原始流还是返回一个新流?
消费流...消费流。如果你想两次消费数据,你需要缓存它。以上是关于如何等待 openRead 函数在一个文件上完成,然后再转到下一个文件?的主要内容,如果未能解决你的问题,请参考以下文章