====== Die Dateisystem-Sammlung ======
Sechs Units, die **fremde Dateisysteme lesen** — jedes in einer eigenen Unit, weil sie sich im Aufbau grundlegend unterscheiden. Dazu eine siebte, die die Frage davor beantwortet: wo auf dem Datenträger fängt das Dateisystem überhaupt an?
→ [[lyx_-_programmiersprache:units:fs|std.fs (Datei-I/O)]] · [[lyx_-_programmiersprache:units|Units-Übersicht]] · [[lyx_-_programmiersprache:guides:dateisysteme-lesen|Guide: Fremde Dateisysteme lesen]] · [[lyxos:iofs|Lyx OS: IOFS]]
----
===== Die Units =====
^ Unit ^ Liest ^ Aufbauprinzip ^ Umfang ^
| [[lyx_-_programmiersprache:units:fs:part|std.fs.part]] | MBR und GPT | Partitionstabelle — **kein** Dateisystem | 12 Funktionen |
| [[lyx_-_programmiersprache:units:fs:fat|std.fs.fat]] | FAT12/16/32 | Clusterkette in einer Zuordnungstabelle | 21 Funktionen |
| [[lyx_-_programmiersprache:units:fs:exfat|std.fs.exfat]] | exFAT | Clusterkette, aber ganz andere Strukturen als FAT32 | 15 Funktionen |
| [[lyx_-_programmiersprache:units:fs:ext4|std.fs.ext4]] | ext2, ext3, ext4 | **Inode-Tabelle** plus Extent-Bäume | 13 Funktionen |
| [[lyx_-_programmiersprache:units:fs:ntfs|std.fs.ntfs]] | NTFS | **Master File Table**, Attribute, Datenläufe | 14 Funktionen |
| [[lyx_-_programmiersprache:units:fs:squashfs|std.fs.squashfs]] | SquashFS 4.0 | **komprimierte** Metadatenblöcke, Inode-Referenzen | 20 Funktionen |
**Alle sechs lesen nur.** Schreiben verlangt bei jedem Format mehr als das Spiegelbild des Lesens: bei FAT die Pflege beider FAT-Kopien, bei exFAT zusätzlich Belegungsbitmap und Prüfsummen, bei ext3/ext4 und NTFS die Journalführung — und ein Schreiber, der das Journal nicht führt, macht aus einem Absturz einen Datenverlust. SquashFS ist von Haus aus nur lesbar; ein Abbild zu ändern hieße, es neu zu bauen (''mksquashfs'').
----
===== Das gemeinsame Muster =====
Alle Units arbeiten gleich: **offener Deskriptor plus Byte-Versatz**. Ob dahinter eine Abbilddatei, eine Partition oder ein ganzes Gerät liegt, ist ihnen gleich.
var fd: int64 := open("/dev/sda"c, 0, 0);
var t: PartTable := PartScan(fd, 512); // wo faengt was an?
var off: int64 := PartByteOffset(t, 0); // Byte-Versatz der 1. Partition
var vol: Ext4Volume := Ext4Mount(fd, off); // dort einhaengen
Damit ist ''PartByteOffset'' das Bindeglied: sein Rückgabewert ist genau das, was ''FatMount'', ''ExfatMount'', ''Ext4Mount'', ''NtfsMount'' und ''SquashMount'' als zweites Argument erwarten.
^ Schritt ^ FAT ^ exFAT ^ ext4 ^ NTFS ^ SquashFS ^
| Einhängen | ''FatMount'' | ''ExfatMount'' | ''Ext4Mount'' | ''NtfsMount'' | ''SquashMount'' |
| Verzeichnis öffnen | ''FatDirOpen'' | ''ExfatDirOpen'' | ''Ext4DirOpen'' | (über ''NtfsFindInDir'') | ''SquashDirOpen'' |
| Eintrag holen | ''FatDirNext'' | ''ExfatDirNext'' | ''Ext4DirNext'' | ''NtfsDirCount'' | ''SquashDirNext'' |
| Pfad auflösen | ''FatFindPath'' | ''ExfatFindPath'' | ''Ext4FindPath'' | ''NtfsFindPath'' | ''SquashFindPath'' |
| Datei lesen | ''FatReadFile'' | ''ExfatReadFile'' | ''Ext4ReadFile'' | ''NtfsReadFile'' | ''SquashReadFile'' |
Die Namen folgen demselben Schnitt — der **Aufbau dahinter** ist jedes Mal ein anderer, und genau deshalb gibt es keine gemeinsame Oberschicht: eine Schnittstelle, die FAT-Clusterketten und NTFS-Datenläufe unter einen Hut zwängt, verliert bei beiden die Eigenheiten, auf die es beim Lesen ankommt.
----
===== Warum je eine eigene Unit =====
* **exFAT ist kein FAT32.** Es teilt den Namen und die Grundidee — Cluster, eine Zuordnungstabelle —, aber kaum ein Strukturfeld. Sektor- und Clustergröße stehen als **Zweierpotenz-Exponent** da, nicht als Zahl; es gibt keine feste Wurzel und keine 8.3-Namen; und zusammenhängende Dateien tragen ''NoFatChain'' und stehen **gar nicht** in der Tabelle.
* **ext4 kennt Inodes.** Der Verzeichniseintrag trägt nur einen Namen und eine Nummer, alles Weitere steht im Inode — Größe, Rechte, Zeiten und der Weg zu den Blöcken.
* **NTFS hat die Master File Table.** Statt einer Tabelle, die Blöcke aufzählt, ist dort jede Datei ein Satz aus Attributen; die Daten sind nur eines davon (''$DATA''), und bei kleinen Dateien stehen sie **mitten im Satz**.
* **SquashFS ist komprimiert.** Es gibt keine Cluster und keine Zuordnungstabelle; eine Inode-Referenz ist keine Nummer, sondern ein Paar aus Blockadresse und Versatz im entpackten Block.
----
===== Grenzen im Überblick =====
^ Unit ^ Nicht enthalten — und im Zweifel **gemeldet**, nicht geraten ^
| ''std.fs.part'' | Nur MBR und GPT; kein APM, keine BSD-Disklabels. Höchstens ''PART_MAX'' = 128 Einträge, damit ein beschädigtes Eintragsfeld nicht in eine unbegrenzte Belegung läuft |
| ''std.fs.ext4'' | Die **doppelt indirekte** Blockzuordnung (jenseits von 12 + n + n² Blöcken, bei 4-KiB-Blöcken erst über 4 GiB); still das Falsche zu liefern wäre schlimmer als die Meldung |
| ''std.fs.ntfs'' | Komprimierte und verschlüsselte Dateien |
| ''std.fs.squashfs'' | Erweiterte Attribute, Gerätedateien, Sockets. Welche Kompressionsverfahren wirklich gehen, sagt ''SquashCompressionUnterstuetzt'' |
----
===== Prüfstand =====
Jede Unit hat einen eigenen Testlauf gegen **echte Abbilder**, die im Test erzeugt werden:
^ Unit ^ Test ^ Prüfungen ^
| ''std.fs.fat'' | ''tests/fat_test.sh'' | 94 |
| ''std.fs.exfat'' | ''tests/exfat_test.sh'' | 42 |
| ''std.fs.ext4'' | ''tests/ext4_test.sh'' | 53 |
| ''std.fs.ntfs'' | ''tests/ntfs_test.sh'' | 33 |
| ''std.fs.part'' | ''tests/part_test.sh'' | 47 |
| ''std.fs.squashfs'' | ''tests/squashfs_test.sh'' | 37 |
Letzte Aktualisierung: 2026-09-05 — Seite neu angelegt; erhoben aus ''std/fs/*.lyx'' im Compiler-Repo.
Prüflauf 2026-09-05 mit ''doku-pruefer.py'' (Repo-Compiler **lyxc 1.2.2A**): 7 Vollprogramme der Sammlung, 7 übersetzen, 0 echte Fehler; 53 Aufrufe gegen die ''pub fn''-Signaturen gehalten, 0 Abweichungen.