Start · Sprachen · JavaScript · Referenz · TextEncoderStream

TextEncoderStream

Schnittstelle

Ein <code>TransformStream</code>, der einen Strom von Zeichenketten in UTF-8-kodierte <code>Uint8Array</code>-Blöcke umwandelt.

seit JavaScript Baseline 2022: Chrome 71, Edge 79, Firefox 105, Sa Kategorie: webapi

Signatur

interface TextEncoderStream

Beschreibung

TextEncoderStream ist die Stream-Variante von TextEncoder aus der Encoding API. Es handelt sich um ein Transform-Stream-Paar aus writable (nimmt Zeichenketten entgegen) und readable (liefert Uint8Array-Blöcke mit UTF-8-Bytes). Deshalb lässt es sich direkt in ReadableStream.prototype.pipeThrough() einsetzen.

Man nutzt es immer dann, wenn Text schrittweise erzeugt und als Bytes weitergereicht werden soll, etwa für einen Streaming-Upload per fetch(), zum Schreiben in einen FileSystemWritableFileStream, für die Kompression mit CompressionStream oder in eine serielle Schnittstelle (Web Serial). Der Text muss dabei nicht erst komplett im Speicher liegen.

Wichtig: TextEncoderStream kann Surrogatpaare korrekt verarbeiten, die über zwei Chunks verteilt sind. Ein hohes Surrogat am Ende eines Chunks wird zurückgehalten, bis der nächste Chunk ankommt. Die Ausgabe ist immer UTF-8, ein anderes Encoding lässt sich nicht wählen. Die Eigenschaft encoding liefert deshalb stets "utf-8".

Eigenschaften (alle schreibgeschützt): encoding (immer "utf-8"), readable (ReadableStream<Uint8Array>) und writable (WritableStream<string>).

Parameter

Name Typ Default Beschreibung
$(keine) — Der Konstruktor new TextEncoderStream() hat keine Parameter. Das Ziel-Encoding ist fest UTF-8.

Rückgabewert

Typ
TextEncoderStream
Beschreibung
Eine neue Instanz mit den Eigenschaften readable, writable und encoding. Sie lässt sich als Transform-Stream an pipeThrough() übergeben.

Beispiele

Instanziierung und direkte Nutzung von writable/readable

const encoder = new TextEncoderStream();
console.log(encoder.encoding);

const writer = encoder.writable.getWriter();
const reader = encoder.readable.getReader();

// Schreiben und Lesen parallel, sonst blockiert der Backpressure-Mechanismus
writer.write('Grüße');
writer.close();

const { value } = await reader.read();
console.log(value);
utf-8 Uint8Array(7) [71, 114, 195, 188, 195, 159, 101]

Text-Stream per pipeThrough in Bytes umwandeln

const zeilen = ['Zeile 1\n', 'Zeile 2\n', 'Ümlaut 3\n'];

const textStream = new ReadableStream({
  start(controller) {
    zeilen.forEach((z) => controller.enqueue(z));
    controller.close();
  }
});

const byteStream = textStream.pipeThrough(new TextEncoderStream());

let gesamt = 0;
for await (const chunk of byteStream) {
  gesamt += chunk.byteLength;
}
console.log(`Bytes: ${gesamt}`);
Bytes: 26

Text komprimiert als Blob erzeugen

const csv = ReadableStream.from(['id;name\n', '1;Anna\n', '2;Jörg\n']);

const gzipStream = csv
  .pipeThrough(new TextEncoderStream())
  .pipeThrough(new CompressionStream('gzip'));

const blob = await new Response(gzipStream).blob();
console.log(blob.size > 0);
true

Streaming-Upload mit fetch (Chromium)

const quelle = new ReadableStream({
  async start(controller) {
    for (let i = 0; i < 3; i++) {
      controller.enqueue(`Event ${i}\n`);
      await new Promise((r) => setTimeout(r, 500));
    }
    controller.close();
  }
});

await fetch('/api/log', {
  method: 'POST',
  headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  body: quelle.pipeThrough(new TextEncoderStream()),
  duplex: 'half' // Pflicht bei Stream-Bodies
});

// Wichtig · Fallstricke

  • Nur Zeichenketten schreiben: Andere Werte werden per String() umgewandelt. Ein Objekt wird so zu "[object Object]". Für JSON also vorher JSON.stringify() aufrufen.
  • Nur UTF-8: Andere Encodings wie ISO-8859-1 oder UTF-16 werden nicht unterstützt. Für das Dekodieren gibt es das Gegenstück TextDecoderStream, das mehrere Encodings kann.
  • Backpressure: Wenn man über writer.write() schreibt, ohne die readable-Seite zu lesen, bleibt das zurückgegebene Promise hängen. Deshalb nicht mit await auf write() warten, bevor ein Leser aktiv ist.
  • Einzelne Surrogate: Ein hohes Surrogat ohne Partner am Ende des Streams wird als Ersatzzeichen U+FFFD (EF BF BD) ausgegeben.
  • Kompatibilität: Seit 2022 in allen aktuellen Browsern verfügbar (Firefox erst ab Version 105). In Node.js gibt es die Schnittstelle ab 16.6 über stream/web und ab 18 global. ReadableStream.from() und Stream-Bodies bei fetch (duplex: 'half') werden nicht überall unterstützt.
  • Für einmalige, vollständig vorliegende Texte ist TextEncoder.prototype.encode() einfacher und schneller.