====== std.zip — ZIP-Archive lesen und schreiben ======
''std.zip'' liest und schreibt ZIP-Archive nach PKWARE APPNOTE. Die Unit implementiert die Kompressionsmethoden stored (method 0) und deflated (method 8, via ''std.zlib'') und wählt beim Schreiben automatisch die günstigere Variante. Keine externen Abhängigkeiten außer ''std.zlib'' für die Kompression.
→ [[lyx_-_programmiersprache:units:archiv|Archiv-Übersicht]] · [[lyx_-_programmiersprache:units:tar|std.tar]] · [[lyx_-_programmiersprache:units:rar|std.rar]] · [[lyx_-_programmiersprache:units:iso|std.iso]] · [[lyx_-_programmiersprache:units|Standard Library]]
Alle Beispiele dieser Seite sind mit ''lyxc 1.0.21A'' übersetzt und ausgeführt; die gezeigten Ausgaben sind echte Programmausgaben.
**Einschränkungen:** Max. 4096 Einträge pro Archiv. Keine ZIP64-Unterstützung — Einzeldateien sind auf ~2 GB begrenzt. Kein Passwortschutz.
----
===== Konstanten =====
^ Konstante ^ Wert ^ Bedeutung ^
| ''ZIP_MAX_ENTRIES'' | 4096 | Maximale Einträge pro Archiv |
| ''ZIP_METHOD_STORE'' | 0 | Kompressionsmethode: unkomprimiert |
| ''ZIP_METHOD_DEFLATE'' | 8 | Kompressionsmethode: DEFLATE |
| ''ZIP_STORE_THRESHOLD'' | 64 | Dateien ≤ 64 Bytes werden immer stored |
| ''ZIP_ERR_OK'' | 0 | Kein Fehler |
| ''ZIP_ERR_NOTZIP'' | 1 | Keine gültige ZIP-Datei |
| ''ZIP_ERR_IO'' | 2 | I/O-Fehler beim Lesen oder Schreiben |
| ''ZIP_ERR_CORRUPT'' | 3 | Archiv beschädigt |
| ''ZIP_ERR_FULL'' | 4 | ZIP_MAX_ENTRIES erreicht |
----
===== Lesen (ZipReader) =====
^ Funktion ^ Rückgabe ^ Beschreibung ^
| ''ZipOpen(path)'' | ''int64'' Handle oder 0 | Öffnet ZIP-Archiv aus Datei |
| ''ZipClose(handle)'' | ''void'' | Gibt Handle und alle Ressourcen frei |
| ''ZipCount(handle)'' | ''int64'' | Anzahl der Einträge |
| ''ZipName(handle, idx)'' | ''int64'' pchar | Name des idx-ten Eintrags (interner Puffer — nicht free'n) |
| ''ZipUncompSize(handle, idx)'' | ''int64'' | Unkomprimierte Größe in Bytes |
| ''ZipRead(handle, idx, outBuf, maxLen)'' | ''int64'' Bytes oder -1 | Dekomprimiert Eintrag in outBuf |
| ''ZipFind(handle, name)'' | ''int64'' Index oder -1 | Sucht Eintrag nach Namen |
''ZipRead'' dekomprimiert automatisch (stored oder deflated). ''outBuf'' muss mindestens ''ZipUncompSize'' Bytes groß sein.
import std.zip;
import std.alloc;
import std.string;
fn main(): int64 {
// Schreiben: kurze Eintraege werden gespeichert, lange komprimiert
var w: int64 := ZipWriterNew();
ZipWriterAdd(w, "README.txt"c, "Hallo aus Lyx!"c as int64, 14);
var lang: pchar := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"c;
ZipWriterAdd(w, "daten/gross.txt"c, lang as int64, StrLen(lang));
var rc: int64 := ZipWriterSave(w, "/tmp/lyx_test.zip"c);
ZipWriterFree(w);
PrintLn(StrConcat("Save rc (0 = ok): ", IntToStr(rc)));
// Lesen
var h: int64 := ZipOpen("/tmp/lyx_test.zip"c);
if (h == 0) { PrintLn("ZipOpen fehlgeschlagen"); return 1; }
PrintLn(StrConcat("Eintraege: ", IntToStr(ZipCount(h))));
var i: int64 := 0;
while (i < ZipCount(h)) {
PrintLn(StrConcat(StrConcat(" ", ZipName(h, i) as pchar),
StrConcat(" ", IntToStr(ZipUncompSize(h, i)))));
i := i + 1;
}
var idx: int64 := ZipFind(h, "README.txt"c);
var buf: int64 := alloc(256);
var n: int64 := ZipRead(h, idx, buf, 256);
PrintLn(StrConcat(StrConcat("Inhalt (", IntToStr(n)), StrConcat(" Byte): ", buf as pchar)));
ZipClose(h);
return 0;
}
Save rc (0 = ok): 0
Eintraege: 2
README.txt 14
daten/gross.txt 96
Inhalt (14 Byte): Hallo aus Lyx!
Das erzeugte Archiv ist mit den üblichen Werkzeugen lesbar:
$ unzip -l /tmp/lyx_test.zip
14 2017-01-01 00:00 README.txt
96 2017-01-01 00:00 daten/gross.txt
''README.txt'' bleibt mit 14 Byte unter ''ZIP_STORE_THRESHOLD'' und wird //stored// abgelegt, ''daten/gross.txt'' mit 96 Byte deflatiert — die Entscheidung trifft ''ZipWriterSave'' je Eintrag selbst.
----
===== Schreiben (ZipWriter) =====
^ Funktion ^ Rückgabe ^ Beschreibung ^
| ''ZipWriterNew()'' | ''int64'' Writer-Handle | Erstellt neuen leeren Writer |
| ''ZipWriterAdd(writer, name, data, dataLen)'' | ''int64'' Fehlercode | Fügt Eintrag hinzu (kopiert Name + Daten) |
| ''ZipWriterSave(writer, path)'' | ''int64'' Fehlercode | Schreibt Archiv in Datei |
| ''ZipWriterFree(writer)'' | ''void'' | Gibt Writer und alle Einträge frei |
Methode wird automatisch gewählt: stored für ≤ 64 Bytes und wenn deflate keine Verbesserung bringt, sonst deflated.
----
===== Fallstricke =====
* **Pfade und Eintragsnamen sind ''pchar''.** Seit [[https://github.com/SEOLizer/LyX-Compiler/issues/1618|#1618]] gilt das einheitlich in ''std.zip'', ''std.tar'', ''std.rar'' und ''std.iso''; der frühere Cast ''%%"archiv.zip"c as int64%%'' entfällt. Der **Datenparameter** bleibt ''int64'' — das ist ein Binärpuffer, kein Text.
* **''ZipWriterSave'' liefert 0 bei Erfolg**, ''ZipOpen'' dagegen 0 im Fehlerfall. Die beiden Rückgaben bedeuten das Gegenteil voneinander.
* **Der Zeitstempel ist fest** auf den 1. Januar 2017 gesetzt; ''std.zip'' schreibt keine echte Änderungszeit.
* **''ZipRead'' terminiert nicht** — für die Textausgabe selbst ein Nullbyte hinter die gelesenen Bytes setzen.
* **''ZipFind'' vergleicht den vollständigen Namen** einschließlich Verzeichnisanteil (''daten/gross.txt'').
* **Kein ZIP64, kein Passwort, keine Verzeichniseinträge** — Ordner entstehen allein durch Schrägstriche im Namen.
----
===== Speicherverwaltung =====
^ Handle ^ Freigabe ^
| ''ZipOpen'' → Reader-Handle | ''ZipClose(handle)'' |
| ''ZipWriterNew'' → Writer-Handle | ''ZipWriterFree(writer)'' |
| ''ZipName'' → interner Puffer | **nicht free'n** — gehört dem Handle |
| ''outBuf'' in ''ZipRead'' | Aufrufer allokiert, Aufrufer gibt frei |
Letzte Aktualisierung: 2026-08-13 — Beispiele lauffähig gemacht, ausgeführt und mit ''unzip'' gegengelesen (lyxc 1.0.17K); Fallstricke ergänzt (Pfad als Adresse, festes Datum 2017-01-01, gegenläufige Rückgabewerte von Open und Save).
Codebeispiele geprüft: gegen **lyxc 1.2.5C** übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die ''pub fn''-Signaturen in ''aurum/std'' gehalten, 0 Abweichungen).