如何等待 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&lt;List&lt;int&gt;&gt;' 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&lt;List&lt;dynamic&gt;&gt;,因为它是一个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 函数在一个文件上完成,然后再转到下一个文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何等待函数在javascript中完成?

如何等待module.export函数完成请求,然后再将其返回值分配给不同JS文件中的变量[重复]

如何在 Node.js 中等待一个函数完成? [复制]

在返回函数的变量之前,如何等待 promise 完成?

在 selenium 和 c# 中等待完成的下载文件

如何让 Lambda 函数等待异步操作完成?