====== std.rar — RAR5-Archive lesen ====== ''std.rar'' liest Archive im **RAR5**-Format (Signatur ''Rar!\x1A\x07\x01\x00''). Die Unit ist ein reiner Reader ohne externe Abhängigkeiten: Sie zerlegt die Blockstruktur des Archivs und stellt die enthaltenen Dateien über dasselbe Handle-Muster bereit wie ''std.zip'' und ''std.tar''. → [[lyx_-_programmiersprache:units:archiv|Archiv-Übersicht]] · [[lyx_-_programmiersprache:units:zip|std.zip]] · [[lyx_-_programmiersprache:units:tar|std.tar]] · [[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. > **Nur unkomprimierte Einträge sind sichtbar.** Der RAR-Kompressionsalgorithmus ist proprietär und in ''std.rar'' nicht umgesetzt. Einträge mit einer anderen Methode als //stored// werden beim Öffnen **stillschweigend übersprungen** — sie erscheinen weder in ''RarCount'' noch über ''RarFind''. Da handelsübliche Packer standardmäßig komprimieren, sind die meisten RAR-Archive aus freier Wildbahn für diese Unit **leer**. > > Wer RAR nur lesen muss und die Archive selbst erzeugt: mit „Speichern"/„store" packen. Wer freie Wahl hat, nimmt [[lyx_-_programmiersprache:units:zip|std.zip]] oder [[lyx_-_programmiersprache:units:tar|std.tar]] — beide lesen **und** schreiben. **Kein Writer.** RAR-Archive lassen sich mit ''std.rar'' nicht erzeugen; es gibt keine ''RarWriter*''-Funktionen. ---- ===== Konstanten ===== ^ Konstante ^ Wert ^ Bedeutung ^ | ''RAR_MAX_ENTRIES'' | 4096 | Höchstzahl erfasster Einträge | | ''RAR_ERR_OK'' | 0 | kein Fehler | | ''RAR_ERR_NOTRAR'' | 1 | keine gültige RAR5-Datei | | ''RAR_ERR_IO'' | 2 | Datei nicht lesbar | | ''RAR_ERR_CORRUPT'' | 3 | Archiv beschädigt | | ''RAR_ERR_COMPRESSED'' | 4 | Eintrag ist komprimiert | Die Fehlercodes sind für eigene Fehlerbehandlung gedacht: Die Funktionen selbst melden Fehler über ''0'' (kein Handle) beziehungsweise ''-1''. ---- ===== Funktionen ===== ^ Signatur ^ Rückgabe ^ Beschreibung ^ | ''RarOpen(path: pchar): int64'' | Handle oder ''0'' | Liest das Archiv vollständig in den Speicher und erfasst alle //stored//-Einträge. ''0'' bei fehlender Datei, zu kurzer Datei oder falscher Signatur. | | ''RarClose(handle: int64): void'' | – | Gibt Rohdaten, Namen und Eintragstabelle frei. | | ''RarCount(handle: int64): int64'' | Anzahl | Zahl der **erfassten** Einträge — komprimierte sind nicht dabei. | | ''RarName(handle: int64, idx: int64): int64'' | Zeiger | Dateiname als nullterminierter Text. **Interner Puffer — nicht freigeben.** | | ''RarSize(handle: int64, idx: int64): int64'' | Bytes | Größe der gespeicherten Daten. | | ''RarRead(handle: int64, idx: int64, outBuf: int64, maxLen: int64): int64'' | gelesene Bytes | Kopiert die Daten in einen selbst angelegten Puffer, höchstens ''maxLen''. | | ''RarFind(handle: int64, name: int64): int64'' | Index oder ''-1'' | Sucht einen Eintrag über den vollständigen Namen. | ''RarOpen'' erwartet den Pfad als ''pchar'' (seit #1264), die übrigen Funktionen arbeiten mit Adressen. ---- ===== Beispiel ===== import std.rar; import std.alloc; import std.string; fn main(): int64 { var h: int64 := RarOpen("/tmp/lyx_test.rar"c); if (h == 0) { PrintLn("kein RAR5-Archiv oder nicht lesbar"); return 1; } PrintLn(StrConcat("stored-Eintraege: ", IntToStr(RarCount(h)))); var i: int64 := 0; while (i < RarCount(h)) { PrintLn(StrConcat(StrConcat(" ", RarName(h, i) as pchar), StrConcat(" ", IntToStr(RarSize(h, i))))); i := i + 1; } var idx: int64 := RarFind(h, "README.txt"c); if (idx >= 0) { var buf: int64 := alloc(256); var n: int64 := RarRead(h, idx, buf, 256); poke8(buf + n, 0); PrintLn(StrConcat("Inhalt: ", buf as pchar)); } RarClose(h); return 0; } Gegen ein RAR5-Archiv mit zwei gespeicherten Dateien: stored-Eintraege: 2 README.txt 14 daten/notiz.txt 13 Inhalt: Hallo aus Lyx! Dasselbe Programm gegen ein Archiv, das eine gespeicherte **und** eine komprimierte Datei enthält: stored-Eintraege: 1 stored.txt 13 ''packed.txt'' fehlt — obwohl ''7z l'' beide Einträge auflistet. Genau das meint der Warnkasten oben. ---- ===== Was der Reader vom Archiv liest ===== RAR5 besteht aus einer Signatur (8 Byte) und daran anschließenden Blöcken. Jeder Block beginnt mit CRC32 und Headergröße, danach folgen Typ und Flags als //vint// (7 Bit je Byte, oberstes Bit = „noch ein Byte"). ^ Blocktyp ^ Wert ^ Behandlung ^ | MAIN | 1 | übersprungen | | FILE | 2 | ausgewertet — siehe unten | | ENDARC | 5 | beendet den Durchlauf | | alle übrigen (SERVICE, CRYPT …) | – | übersprungen | Aus einem FILE-Header liest ''std.rar'': Dateiflags, entpackte Größe, Attribute, optional Zeitstempel und CRC32, die Kompressionsinformation, das Wirtssystem und den Namen. Ein Eintrag wird nur übernommen, wenn **alle** vier Bedingungen zutreffen: * es ist kein Verzeichnis (Flag-Bit 0 nicht gesetzt), * die Kompressionsmethode ist ''0'' (//stored//; Bits 7–9 der Kompressionsinformation), * die Namenslänge liegt zwischen 1 und 511 Byte, * Datenbereich und Header liegen vollständig innerhalb der Datei. > **Die Header-Prüfsumme wird gelesen, aber nicht geprüft.** Ein beschädigtes Archiv fällt deshalb nicht durch den CRC32-Vergleich auf, sondern erst, wenn Längenangaben aus der Datei laufen — dann bricht der Durchlauf ab und die bis dahin gefundenen Einträge bleiben stehen. ''RarCount'' kann also kleiner sein als der tatsächliche Archivinhalt, ohne dass ein Fehler gemeldet wird. ---- ===== Fallstricke ===== * **Ein leeres Ergebnis heißt nicht „leeres Archiv".** ''RarCount'' = 0 bedeutet meistens: alle Einträge sind komprimiert. Vor der Fehlersuche mit ''7z l'' oder ''unrar l'' gegenprüfen. * **Verzeichniseinträge fehlen** — sie werden nicht erfasst. Die Ordnerstruktur steckt nur in den Dateinamen (''daten/notiz.txt''). * **Das Archiv liegt vollständig im Speicher.** ''RarOpen'' liest die ganze Datei; bei mehreren hundert MB entsprechend viel Hauptspeicher. Es gibt keinen streamenden Zugriff. * **Namen sind interne Puffer**: ''RarName'' nie freigeben, und nach ''RarClose'' nicht mehr verwenden. * **''RarRead'' terminiert nicht.** Der Rückgabewert ist die Zahl der kopierten Bytes; wer den Puffer als Text ausgeben will, setzt selbst ein Nullbyte dahinter (siehe Beispiel). * **Mehrteilige Archive (''.part1.rar'') und verschlüsselte Archive** werden nicht unterstützt; verschlüsselte Blöcke erscheinen wie unbekannte Blocktypen und werden übersprungen. * **RAR4 (''Rar!\x1A\x07\x00'') wird abgewiesen** — die Signaturprüfung verlangt RAR5. ---- ===== Vergleich mit den anderen Archiv-Units ===== ^ Unit ^ Lesen ^ Schreiben ^ Kompression ^ | [[lyx_-_programmiersprache:units:zip|std.zip]] | ja | ja | DEFLATE über ''std.zlib'' | | [[lyx_-_programmiersprache:units:tar|std.tar]] | ja | ja | keine (mit ''std.gzip'' kombinierbar) | | **std.rar** | **nur stored** | **nein** | keine | | [[lyx_-_programmiersprache:units:iso|std.iso]] | ja | ja | keine | ---- **Weiterführend:** [[lyx_-_programmiersprache:units:archiv|Archiv — ZIP, TAR, RAR, ISO]] · [[lyx_-_programmiersprache:units:zip|std.zip]] · [[lyx_-_programmiersprache:units:gzip|std.gzip]] **Quelle:** ''std/rar.lyx'' (311 Zeilen) Letzte Aktualisierung: 2026-08-13 — Seite neu angelegt; sie fehlte bisher, obwohl die Archiv-Übersicht auf sie verlinkte. Inhalt gegen ''std/rar.lyx'' geschrieben und mit ''lyxc 1.0.21A'' gegen selbst erzeugte RAR5-Archive geprüft (eines nur mit //stored//, eines gemischt). 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).