Signatur
Beschreibung
DecompressionStream gehört zur Compression Streams API und entpackt komprimierte Binärdaten direkt im Browser bzw. in Node.js – ohne Bibliotheken wie pako oder fflate. Das Objekt stellt ein Paar aus writable (Eingang für komprimierte Bytes) und readable (Ausgang für entpackte Bytes) bereit und lässt sich deshalb einfach mit ReadableStream.prototype.pipeThrough() in eine Stream-Kette einhängen.
Typische Einsatzfälle sind das Entpacken von .gz-Dateien, die per fetch() geladen oder vom Nutzer über <input type="file"> ausgewählt wurden, das Lesen komprimierter Daten aus IndexedDB oder localStorage (Base64) sowie das Verarbeiten großer Datenmengen, ohne alles gleichzeitig im Speicher zu halten – die Dekompression erfolgt stückweise (chunk-basiert).
Unterstützt werden die Formate "gzip" (RFC 1952), "deflate" (zlib-Format, RFC 1950) und "deflate-raw" (reines DEFLATE ohne Header, RFC 1951). Die Eingabe-Chunks müssen BufferSource-Werte sein (ArrayBuffer, TypedArray, DataView); die Ausgabe besteht aus Uint8Array-Chunks. Für Text schaltet man anschließend einen TextDecoderStream dahinter.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $format Pflicht | "gzip" | "deflate" | "deflate-raw" | Kompressionsformat der Eingabedaten. Ein unbekannter Wert wirft beim Konstruktor-Aufruf einen TypeError. Der Wert muss zum tatsächlichen Format passen, sonst schlägt die Dekompression mit einem Fehler fehl. |
Rückgabewert
readable (ReadableStream<Uint8Array>, liefert die entpackten Bytes) und writable (WritableStream<BufferSource>, nimmt die komprimierten Bytes entgegen).Beispiele
Gzip-Datei per fetch laden und als Text lesen
const loadGzipText = async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Bytes entpacken und direkt als Text dekodieren
const textStream = response.body
.pipeThrough(new DecompressionStream('gzip'))
.pipeThrough(new TextDecoderStream());
return await new Response(textStream).text();
};
const text = await loadGzipText('/data/export.json.gz');
const data = JSON.parse(text);
console.log(`Datensätze: ${data.length}`);
Roundtrip: komprimieren und wieder entpacken
const compress = async (str) => {
const stream = new Blob([str]).stream()
.pipeThrough(new CompressionStream('deflate-raw'));
return new Uint8Array(await new Response(stream).arrayBuffer());
};
const decompress = async (bytes) => {
const stream = new Blob([bytes]).stream()
.pipeThrough(new DecompressionStream('deflate-raw'));
return await new Response(stream).text();
};
const original = 'Hallo Welt! '.repeat(100);
const packed = await compress(original);
const restored = await decompress(packed);
console.log(original.length, packed.length);
console.log(restored === original);
Vom Nutzer gewählte .gz-Datei zeilenweise verarbeiten (writable/readable manuell)
const input = document.querySelector('#gzFile');
input.addEventListener('change', async () => {
const file = input.files[0];
if (!file) return;
const ds = new DecompressionStream('gzip');
// Datei in den Eingang schreiben (läuft parallel)
file.stream().pipeTo(ds.writable).catch((err) => {
console.error('Eingabe fehlgeschlagen:', err);
});
const reader = ds.readable
.pipeThrough(new TextDecoderStream())
.getReader();
let chars = 0;
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
chars += value.length; // Chunk verarbeiten
}
console.log(`Entpackt: ${chars} Zeichen`);
} catch (err) {
console.error('Keine gültige gzip-Datei:', err.name);
}
});
// Wichtig · Fallstricke
- Kein ZIP-Support:
DecompressionStreamentpackt nur einzelne gzip-/deflate-Datenströme, keine ZIP-Archive mit mehreren Dateien (dafür Bibliotheken wie fflate oder zip.js). Brotli ("br") und Zstandard werden bislang nicht breit unterstützt. - Format muss exakt passen:
"deflate"erwartet einen zlib-Header,"deflate-raw"keinen. Falsches Format oder beschädigte bzw. abgeschnittene Daten führen zu einemTypeErrorbeim Lesen – Fehler also immer mittry/catchbzw..catch()behandeln. - Doppeltes Entpacken vermeiden: Liefert der Server
Content-Encoding: gzip, entpackt der Browser bereits automatisch; ein zusätzlicherDecompressionStreamschlägt dann fehl. Nur für Dateien einsetzen, die tatsächlich komprimiert als Nutzdaten ankommen (z. B.application/gzip). - Nur Binärdaten: Strings als Chunks führen zu einem
TypeError; vorher mitTextEncoderoderBlobin Bytes umwandeln. - Sicherheit: Bei nicht vertrauenswürdigen Daten auf „Dekompressionsbomben“ achten – beim chunkweisen Lesen die entpackte Größe mitzählen und ab einem Limit per
reader.cancel()abbrechen. - Kompatibilität: Seit 2023 in allen modernen Browsern (Firefox ab 113, Safari ab 16.4) verfügbar;
"deflate-raw"kam in Chrome erst mit Version 103. In Node.js global ab Version 18 (vorher übernode:stream/web). Ältere Umgebungen per Feature-Test'DecompressionStream' in globalThisprüfen.