如何在Dart中异步读取文件?

时间:2013-04-16 06:52:54

标签: dart

以上问题是在Dart Google+社区提出的,并没有给出明确答案,所以我想我会在这里重复这个问题,因为,我真的很想知道。以下是Dart社区的帖子:

https://plus.google.com/u/0/103493864228790779294/posts/U7VTyX5h7HR

那么,有没有错误处理的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

您链接的问题是异步读取多个文件的内容,这是一个更难的问题。我认为Florian的解决方案没有问题。简化它,这似乎成功地异步读取文件:

import 'dart:async';
import 'dart:io';

void main() {
  new File('/home/darshan/so/asyncRead.dart')
    .readAsString()
    ..catchError((e) => print(e))
    .then(print);

  print("Reading asynchronously...");
}

输出:

Reading asynchronously...
import 'dart:async';
import 'dart:io';

void main() {
  new File('/home/darshan/so/asyncRead.dart')
    .readAsString()
    ..catchError((e) => print(e))
    .then(print);

  print("Reading asynchronously...");
}

为了记录,这里是Florian Loitsch(稍作修改)解决最初问题的方法:

import 'dart:async';
import 'dart:io';

void main() {
  new Directory('/home/darshan/so/j')
    .list()
    .map((f) => f.readAsString()..catchError((e) => print(e)))
    .toList()
    .then(Future.wait)
    .then(print);

  print("Reading asynchronously...");
}

答案 1 :(得分:3)

Florian解决方案的一个缺点(或不是)它并行读取所有文件,并且只在读取所有内容后处理内容。在某些情况下,您可能希望一个接一个地读取文件,并在阅读下一个文件之前处理它们的内容。

为此,您必须将期货链接在一起,以便下一个readAsString仅在前一个完成之后运行。

Future readFilesSequentially(Stream<File> files, doWork(String)) {
  return files.fold(
      new Future.immediate(null), 
      (chain, file) =>
        chain.then((_) => file.readAsString())
             .then((text) => doWork(text)));
}

在文本上完成的工作甚至可以是异步的,并返回Future。

如果流返回文件A,B和C,然后完成,则程序将:

run readAsString on A
run doWork on the result
when doWork finishes (or the future it returns completes) run readAsString on B
run doWork on the result
when doWork finishes (or the future it returns completes) run readAsString on C
run doWork on the result
when doWork finishes, complete the future returned by processFilesSequentially.

我们需要使用fold而不是listen,这样我们就可以在完成流时完成Future,而不是运行onDone处理程序。