Reputation: 585
The above question was raised at the Dart Google+ community, and no clear answer was given, so I thought I'd repeat the question here because, well, I'd really like to know. Here's the post from the Dart community:
https://plus.google.com/u/0/103493864228790779294/posts/U7VTyX5h7HR
So what is the proper methods to do this, with and without error handling?
Upvotes: 3
Views: 1344
Reputation: 151
A disadvantage (or not) of Florian's solution is that it reads all the files in parallel, and processes the contents only once all the contents are read. In certain cases, you may want to read the files one after another, and process the contents of one file before reading the next.
To do this, you must chain the futures together, so that the next readAsString runs only after the previous one completes.
Future readFilesSequentially(Stream<File> files, doWork(String)) {
return files.fold(
new Future.immediate(null),
(chain, file) =>
chain.then((_) => file.readAsString())
.then((text) => doWork(text)));
}
The work that is done on the text can even be asynchronous, and return a Future.
If the stream returns files A, B, and C, and then is done, then the program will:
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.
We need to use fold rather than listen, so that we get a Future that completes when the stream is done, rather than having an onDone handler run.
Upvotes: 3
Reputation: 34071
The question you linked to was about asynchronously reading the contents of multiple files, which is a harder problem. I think Florian's solution has no issues. Simplifying it, this seems to successfully read a file 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...");
}
This outputs:
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..."); }
For the record, here's Florian Loitsch's (slightly modified) solution to the initial problem:
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...");
}
Upvotes: 6