Stream.transform în Dart

Trece stream-ul printr-un StreamTransformer, de exemplu utf8.decoder sau LineSplitter, și dă stream-ul rezultat.

Sintaxă
Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer)

Ce face Stream.transform

transform aplică un transformator care poate face mai mult decât map: poate uni sau împărți valori, poate păstra o stare între ele. Cel mai des îl vezi la citirea fișierelor: bytes → text cu utf8.decoder, apoi text → linii cu LineSplitter().

Decodorii și codorii din dart:convert sunt transformatori. Poți scrie și propriul transformator cu StreamTransformer.fromHandlers.

Parametri

Parametru Descriere
streamTransformer Transformatorul aplicat.

Ce returnează

Un Stream<S> nou.

Exemple

Exemplul 1: Din bytes în linii de text

Datele vin în bucăți care nu respectă granițele liniilor; LineSplitter le reface corect.

import 'dart:convert';

Future<void> main() async {
  final bucati = Stream<List<int>>.fromIterable([
    utf8.encode('Ana,10\nMih'),
    utf8.encode('ai,8\nIoana'),
    utf8.encode(',9\n'),
  ]);
  final linii = bucati.transform(utf8.decoder).transform(const LineSplitter());
  await for (final linie in linii) {
    final [nume, nota] = linie.split(',');
    print('$nume are nota $nota');
  }
}

Rezultat

Ana are nota 10
Mihai are nota 8
Ioana are nota 9

Exemplul 2: Un transformator propriu

import 'dart:async';

final dubleaza = StreamTransformer<String, String>.fromHandlers(
  handleData: (text, sink) {
    sink.add(text);
    sink.add(text.toUpperCase());
  },
);

Future<void> main() async {
  print(await Stream.fromIterable(['ecou', 'iași']).transform(dubleaza).toList());
}

Rezultat

[ecou, ECOU, iași, IAȘI]

Greșeli frecvente

  • Citești un fișier cu openRead() și împarți bucățile direct cu split('\n'). O linie poate fi tăiată între două bucăți; folosește LineSplitter.

Comenzi înrudite

  • StreamTransformer: Transformă un Stream<S> într-un Stream<T>; fromHandlers îl construiește din funcții pentru date, erori și final.
  • LineSplitter: Împarte un text în rânduri, recunoscând \n, \r\n și \r; funcționează și pe fluxuri cu transform.
  • utf8.decoder: Convertoarele din spatele lui utf8: decoder transformă fluxuri de octeți în text, encoder face invers.
  • File.openRead: Deschide fișierul ca flux de octeți citit pe bucăți; potrivit pentru fișiere mari, rând cu rând.