Inhaltsverzeichnis

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.

Standard Library · std.zip · 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