====== std.tar — TAR-Archive lesen und schreiben ====== ''std.tar'' liest und schreibt TAR-Archive im POSIX ustar Format (IEEE Std 1003.1-1988). TAR komprimiert nicht — es ist ein reines Archivformat. Für komprimierte Archive (.tar.gz, .tar.bz2) wird TAR typischerweise mit ''std.zlib'' kombiniert. → [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:units:zip|std.zip]] · [[lyx_-_programmiersprache:units:rar|std.rar]] **Einschränkungen:** Max. 4096 Einträge, Dateinamen max. 100 Bytes (kein GNU LongLink / split-header). Beim Lesen werden nur reguläre Dateien (typeflag ''0'') erfasst — Verzeichnisse werden übersprungen. ---- ===== Konstanten ===== ^ Konstante ^ Wert ^ Bedeutung ^ | ''TAR_BLOCK_SIZE'' | 512 | Header- und Datei-Blöcke sind je 512 Bytes | | ''TAR_MAX_ENTRIES'' | 4096 | Maximale Einträge pro Archiv | | ''TAR_ERR_OK'' | 0 | Kein Fehler | | ''TAR_ERR_NOTTAR'' | 1 | Keine gültige TAR-Datei | | ''TAR_ERR_IO'' | 2 | I/O-Fehler beim Lesen oder Schreiben | | ''TAR_ERR_CORRUPT'' | 3 | Archiv beschädigt | | ''TAR_ERR_FULL'' | 4 | TAR_MAX_ENTRIES erreicht | ---- ===== Lesen (TarReader) ===== ^ Funktion ^ Rückgabe ^ Beschreibung ^ | ''TarOpen(path)'' | ''int64'' Handle oder 0 | Öffnet TAR-Archiv aus Datei | | ''TarClose(handle)'' | ''void'' | Gibt Handle und alle Ressourcen frei | | ''TarCount(handle)'' | ''int64'' | Anzahl der regulären Datei-Einträge | | ''TarName(handle, idx)'' | ''int64'' pchar | Name des idx-ten Eintrags (interner Puffer — nicht free'n) | | ''TarSize(handle, idx)'' | ''int64'' | Größe in Bytes | | ''TarRead(handle, idx, outBuf, maxLen)'' | ''int64'' Bytes oder -1 | Liest Eintrag in outBuf | | ''TarFind(handle, name)'' | ''int64'' Index oder -1 | Sucht Eintrag nach exaktem Namen | import std.tar; import std.alloc; import std.io; fn TarInhaltLesen(pfad: pchar): void { var t: int64 := TarOpen(pfad as int64); if t == 0 then { PrintLn("Kein gültiges TAR"c); return; } var n: int64 := TarCount(t); Print("Einträge: "c); PrintLn(IntToStr(n)c); var i: int64 := 0; while i < n do { Print(TarName(t, i) as pchar); Print(" "c); PrintLn(IntToStr(TarSize(t, i))c); i := i + 1; } // Einzelne Datei lesen var idx: int64 := TarFind(t, "etc/config.txt"c as int64); if idx >= 0 then { var sz: int64 := TarSize(t, idx); var buf: int64 := alloc(sz + 1); TarRead(t, idx, buf, sz); poke8(buf + sz, 0); PrintLn(buf as pchar); free(buf, sz + 1); } TarClose(t); } ---- ===== Schreiben (TarWriter) ===== ^ Funktion ^ Rückgabe ^ Beschreibung ^ | ''TarWriterNew()'' | ''int64'' Writer-Handle | Erstellt neuen leeren Writer | | ''TarWriterAdd(writer, name, data, dataLen)'' | ''int64'' Fehlercode | Fügt Eintrag hinzu (kopiert Name + Daten) | | ''TarWriterSave(writer, path)'' | ''int64'' Fehlercode | Schreibt Archiv in Datei (POSIX ustar) | | ''TarWriterFree(writer)'' | ''void'' | Gibt Writer und alle Einträge frei | Geschriebene Archive: mode ''0644'', uid/gid 0, mtime 0. Datenblöcke werden auf 512-Byte-Grenzen aufgerundet. Das Archiv endet mit zwei Null-Blöcken (POSIX-Anforderung). import std.tar; import std.alloc; fn TarErstellen(): void { var w: int64 := TarWriterNew(); var inhalt: pchar := "Zeile 1\nZeile 2\n"c; TarWriterAdd(w, "daten/log.txt"c as int64, inhalt as int64, 17); var bin: int64 := alloc(256); // ... bin befüllen ... TarWriterAdd(w, "daten/dump.bin"c as int64, bin, 256); free(bin, 256); var rc: int64 := TarWriterSave(w, "backup.tar"c as int64); if rc != TAR_ERR_OK then { PrintLn("Fehler beim Speichern"c); } TarWriterFree(w); } ---- ===== TAR + Kompression (.tar.gz) ===== TAR selbst komprimiert nicht. Um ein ''.tar.gz'' zu erzeugen, das Archiv in einen Puffer schreiben und anschließend mit ''std.zlib'' komprimieren: import std.tar; import std.zlib; import std.fs; import std.alloc; fn TarGzErstellen(outPfad: pchar): void { // 1. TAR in temporäre Datei schreiben var w: int64 := TarWriterNew(); TarWriterAdd(w, "datei.txt"c as int64, "Inhalt"c as int64, 6); TarWriterSave(w, "/tmp/tmp.tar"c as int64); TarWriterFree(w); // 2. TAR-Inhalt lesen var sz: int64 := FileSize("/tmp/tmp.tar"c as int64); var buf: int64 := alloc(sz); ReadFile("/tmp/tmp.tar"c as int64, buf, sz); // 3. Mit zlib (gzip) komprimieren und speichern var cBuf: int64 := alloc(sz + 65536); var cLen: int64 := GzipCompress(buf as pchar, sz, cBuf as pchar); WriteFile(outPfad as int64, cBuf, cLen); free(buf, sz); free(cBuf, sz + 65536); } ---- ===== Speicherverwaltung ===== ^ Handle ^ Freigabe ^ | ''TarOpen'' → Reader-Handle | ''TarClose(handle)'' | | ''TarWriterNew'' → Writer-Handle | ''TarWriterFree(writer)'' | | ''TarName'' → interner Puffer | **nicht free'n** — gehört dem Handle | | ''outBuf'' in ''TarRead'' | Aufrufer allokiert, Aufrufer gibt frei | Letzte Aktualisierung: 2026-06-13