IOSink în Dart

Destinația în care scrii text sau octeți: un fișier deschis (openWrite), stdout, stderr sau răspunsul HTTP.

Sintaxă
abstract interface class IOSink implements StreamSink<List<int>>, StringSink
void write(Object? object)
void writeln([Object? object = ""])
void writeAll(Iterable objects, [String separator = ""])
void add(List<int> data)

Ce face IOSink

IOSink este o „scurgere” în care trimiți date. Îl primești de la File.openWrite(), iar stdout, stderr și răspunsul unui server (request.response) sunt și ele IOSink. Astfel, același cod poate scrie pe ecran sau într-un fișier.

write(obiect) scrie obiect.toString(), fără rând nou. writeln(obiect) adaugă un rând nou la final (fără argument, scrie doar un rând nou). writeAll(lista, separator) scrie toate elementele, cu separatorul între ele. Pentru octeți se folosește add(octeti). Textul este codificat cu encoding-ul sink-ului (implicit UTF-8).

Scrierile sunt puse într-o coadă și trimise în fundal. La final, apelează close() și așteaptă-l.

Parametri

Parametru Descriere
object Valoarea scrisă (se apelează toString()).
objects, separator La writeAll: elementele și textul pus între ele.

Exemple

Exemplul 1: write, writeln și writeAll într-un fișier

import 'dart:io';

Future<void> main() async {
  final IOSink sink = File('clasament.txt').openWrite();
  sink.write('Clasament ');
  sink.writeln('Olimpiada de informatică');
  sink.writeln();
  sink.writeAll(['1. Ana', '2. Radu', '3. Ioana'], '\n');
  sink.writeln();
  await sink.close();
  print(await File('clasament.txt').readAsString());
}

Rezultat

Clasament Olimpiada de informatică

1. Ana
2. Radu
3. Ioana

Exemplul 2: Aceeași funcție scrie pe ecran sau în fișier

stdout este tot un IOSink, deci funcția primește oricare dintre ele.

import 'dart:io';

void scrieChitanta(IOSink iesire, Map<String, double> produse) {
  produse.forEach((p, pret) => iesire.writeln('${p.padRight(8)} ${pret.toStringAsFixed(2)} lei'));
  final total = produse.values.reduce((a, b) => a + b);
  iesire.writeln('TOTAL    ${total.toStringAsFixed(2)} lei');
}

Future<void> main() async {
  final produse = {'pâine': 4.5, 'lapte': 7.2, 'mere': 6.0};
  scrieChitanta(stdout, produse);

  final fisier = File('chitanta.txt').openWrite();
  scrieChitanta(fisier, produse);
  await fisier.close();
  print('În fișier: ${(await File('chitanta.txt').readAsLines()).length} rânduri');
}

Rezultat

pâine    4.50 lei
lapte    7.20 lei
mere     6.00 lei
TOTAL    17.70 lei
În fișier: 4 rânduri

Greșeli frecvente

  • Scrii în sink după close(): se aruncă StateError.
  • Apelezi writeAll(lista) fără separator și elementele se lipesc: AnaRaduIoana.

Comenzi înrudite

  • IOSink.close: close termină scrierea și închide destinația; flush așteaptă ca datele scrise până acum să ajungă la destinație.
  • File.openWrite: Deschide fișierul pentru scriere și returnează un IOSink în care scrii pe bucăți; trebuie închis cu close().
  • stdout: stdout este ieșirea standard a programului: tot ce apare în terminal; are metodele unui IOSink (write, writeln, writeAll).
  • HttpRequest: HttpRequest este o cerere primită de HttpServer: metoda (GET, POST), adresa (uri), antetele, corpul și răspunsul de trimis.