Inhaltsverzeichnis

Archiv — ZIP, TAR, RAR, ISO

Vier Units für Archiv- und Abbildformate, alle vollständig in Lyx umgesetzt. Externe Bibliotheken braucht keine davon; einzige Abhängigkeit ist std.zlib für die DEFLATE-Kompression in std.zip.

Standard Library · std.gzip · std.zlib

Alle Beispiele dieser Seite sind mit lyxc 1.0.21A übersetzt und ausgeführt; die gezeigten Ausgaben sind echte Programmausgaben. Die erzeugten Archive wurden zusätzlich mit unzip, tar und 7z gegengelesen.


Die vier Units

Unit Lesen Schreiben Kompression Beschreibung
std.zip ja ja DEFLATE (automatisch) ZIP nach PKWARE APPNOTE; bis 4096 Einträge, kein ZIP64, kein Passwort
std.tar ja ja keine POSIX ustar; für .tar.gz mit std.gzip kombinieren
std.rar nur stored nein keine RAR5-Reader; komprimierte Einträge sind unsichtbar (proprietärer Algorithmus)
std.iso ja ja keine ISO 9660 Level 1; Reader läuft den ganzen Verzeichnisbaum ab, Writer erzeugt ein flaches Wurzelverzeichnis

Welches Format wofür

Aufgabe Empfehlung Warum
Dateien austauschen std.zip überall lesbar, komprimiert automatisch
Sicherung oder Auslieferungspaket std.tar + std.gzip Rechte und Pfade bleiben erhalten, Kompression getrennt wählbar
Viele kleine Dateien bündeln, Größe egal std.tar kein Kompressionsaufwand, einfachstes Format
Bootfähiges CD-, DVD- oder USB-Abbild std.iso einziges Format der vier mit Abbild-Charakter
Fremdes ISO-Abbild auslesen std.iso Reader kennt Unterverzeichnisse
Vorhandenes RAR-Archiv lesen std.rar nur wenn die Einträge stored sind — sonst gar nicht
RAR erzeugen geht nicht std.rar hat keinen Writer; std.zip nehmen

Ein Muster für alle

Die vier Units teilen sich dieselbe Handle-Schnittstelle. Wer eine kennt, kennt alle:

Lesen                                 Schreiben
  Open(pfad)      → Handle              WriterNew()                → Handle
  Count(h)        → Anzahl              WriterAdd(h, name, daten, laenge)
  Name(h, idx)    → Zeiger              WriterSave(h, pfad)        → 0 = ok
  Size(h, idx)    → Bytes               WriterFree(h)
  Find(h, name)   → Index oder -1
  Read(h, idx, puffer, max) → Bytes
  Close(h)

Die Präfixe sind Zip, Tar, Rar und IsoZipCount, TarCount, RarCount, IsoCount. Einzige Abweichung: std.zip nennt die Größenabfrage ZipUncompSize (nicht ZipSize), weil im Archiv zusätzlich die komprimierte Größe steht. std.rar hat nur die linke Spalte.

import std.zip;
import std.tar;
import std.iso;
import std.alloc;
import std.string;

// Dasselbe Muster fuer alle drei Schreiber
fn main(): int64 {
    var z: int64 := ZipWriterNew();
    ZipWriterAdd(z, "README.txt"c, "Hallo aus Lyx!"c as int64, 14);
    PrintLn(StrConcat("ZIP  gespeichert, rc = ", IntToStr(ZipWriterSave(z, "/tmp/demo.zip"c))));
    ZipWriterFree(z);

    var t: int64 := TarWriterNew();
    TarWriterAdd(t, "daten/log.txt"c, "Zeile 1\nZeile 2\n"c as int64, 16);
    PrintLn(StrConcat("TAR  gespeichert, rc = ", IntToStr(TarWriterSave(t, "/tmp/demo.tar"c))));
    TarWriterFree(t);

    var i: int64 := IsoWriterNew();
    IsoWriterAdd(i, "README.TXT"c, "ISO 9660 aus Lyx"c as int64, 16);
    PrintLn(StrConcat("ISO  gespeichert, rc = ", IntToStr(IsoWriterSave(i, "/tmp/demo.iso"c))));
    IsoWriterFree(i);

    // Und wieder lesen - ebenfalls dasselbe Muster
    var h: int64 := ZipOpen("/tmp/demo.zip"c);
    var idx: int64 := ZipFind(h, "README.txt"c);
    var buf: int64 := alloc(256);
    var n: int64 := ZipRead(h, idx, buf, 256);
    poke8(buf + n, 0);
    PrintLn(StrConcat(StrConcat("ZIP  Eintraege: ", IntToStr(ZipCount(h))), StrConcat("   README.txt = ", buf as pchar)));
    ZipClose(h);
    return 0;
}

ZIP  gespeichert, rc = 0
TAR  gespeichert, rc = 0
ISO  gespeichert, rc = 0
ZIP  Eintraege: 1   README.txt = Hallo aus Lyx!

Die drei Dateien sind mit den üblichen Werkzeugen lesbar:

$ unzip -l /tmp/demo.zip
       14  2017-01-01 00:00   README.txt

$ tar -tf /tmp/demo.tar
daten/log.txt

$ 7z l /tmp/demo.iso
                    .....           16           16  README.TXT


Pfadangaben und Rückgabewerte

Zwei Stolperstellen, die sich durch alle vier Units ziehen:

Ebenfalls für alle vier gleich:


Grenzen im Überblick

std.zip std.tar std.rar std.iso
Einträge 4096 4096 4096 4096
Namenslänge Archivgrenze 100 Byte 511 Byte 8.3 vorgesehen
Verzeichnisse im Namen im Namen im Namen (lesend) flach beim Schreiben
Zeitstempel fest 2017-01-01 0 (1970) gelesen, nicht ausgewertet Erstellzeit im Abbild
Kompression DEFLATE ab 65 Byte keine keine keine

Drei dieser Grenzen führen zu stillem Verhalten und sind auf den Einzelseiten belegt:


Und die Kompression?

std.zip bringt DEFLATE selbst mit (über std.zlib) und entscheidet je Eintrag: bis 64 Byte stored, darüber komprimiert. Die anderen drei Formate komprimieren nicht — dafür gibt es eigene Units:

Unit Aufgabe
std.gzip gzip-Ströme lesen und schreiben — die zweite Hälfte von .tar.gz
std.zlib DEFLATE/Inflate und die zlib-Hülle, dazu Adler-32 und CRC-32

Weiterführend: std.zip · std.tar · std.rar · std.iso · Guide: ISO-Abbilder

Letzte Aktualisierung: 2026-08-13 — Schnellstart durch ein lauffähiges Programm ersetzt (die drei alten Ausschnitte waren nie übersetzt worden) und um den Gegenlesetest mit unzip/tar/7z ergänzt. Neu: Format-Wahl mit Begründung, Grenzen-Vergleich der vier Units, die drei still wirkenden Grenzen und der Hinweis auf die uneinheitliche Pfad-Übergabe. Die Seite std.rar ist neu angelegt — sie war hier verlinkt, existierte aber nicht.

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).