I am trying to wrap my head around Dart Streams. In particular this example of the command line utility cat
has the following lines of code:
Stream<List<int>> stream = new File(path).openRead();
// Transform the stream using a `StreamTransformer`. The transformers
// used here convert the data to UTF8 and split string values into
// individual lines.
return stream
.transform(UTF8.decoder)
.transform(const LineSplitter())
.listen((line) {
if (showLineNumbers) {
stdout.write('${lineNumber++} ');
}
stdout.writeln(line);
}).asFuture().catchError((_) => _handleError(path));
The declaration of the
Stream<T>
asStream<List<int>>
has me a bit confused. Why is it not declared as aStream<int>
. How does the List<> type make this different. Are the subscriber events buffered in some way if it is a List?What Type (as in
<T>
) is passed to the first transform? Is it anint
or aList<int>
?What type is passed to each of the next transforms and what determines their type.
Does this example read the entire file before passing the results of the transform to the next transform? If so, is there an example somewhere of how to Stream very large files similar to this Node question Parsing huge logfiles in Node.js - read in line-by-line
UTF8
is a Utf8Codec that extendsCodec<String, List<int>>
. So UTF8.decoder is aConverter<List<int>, String>
that takesList<int>
as parameter.Converter<String, List<String>>
. So it takesString
as parameter. The resulting stream of.transform(const LineSplitter())
is aStream<String>
where each line is sent.File.openRead
doesn't read the entire file before writing the first bytes to the stream. So there's no problem to deal with large files.Alexandre Ardhuin has the first three questions right. The 4th question however is not. After taking this apart and stubbing out my own version of the code I determined the following:
Even on a 37Mb file, the the transforms only get called once.
Here is the code I used to figure it out.