std.fs_ext

Erweitertes Datei-I/O (WP-1): Ergänzt std.fs um positioniertes Lesen/Schreiben (PRead/PWrite), Scatter-Gather-I/O (ReadV/WriteV), Datei-Metadaten (Fstat), Zugriffsprüfung (FileExists), Synchronisierung (Fsync), Größenänderung (Truncate), Verzeichniswechsel und kernelseitigen Dateitransfer (Sendfile).

Standard Library · std.fs · std.inotify


Konstanten

stat-Puffer

Konstante Wert Typ Beschreibung
STAT_SIZE 144 Puffergröße für Fstat (alloc(STAT_SIZE))
STAT_DEV 0 dev_t (8 B) Geräte-ID
STAT_INO 8 ino_t (8 B) Inode-Nummer
STAT_NLINK 16 nlink_t (8 B) Anzahl Hard-Links
STAT_MODE 24 mode_t (4 B) Zugriffsrechte + Dateityp
STAT_UID 28 uid_t (4 B) Eigentümer-UID
STAT_GID 32 gid_t (4 B) Gruppen-GID
STAT_SIZE_F 48 off_t (8 B) Dateigröße in Bytes
STAT_BLKSIZE 56 blksize_t (8 B) Bevorzugte I/O-Blockgröße
STAT_BLOCKS 64 blkcnt_t (8 B) Belegte 512-Byte-Blöcke
STAT_ATIME 72 timespec (16 B) Letzter Zugriff
STAT_MTIME 88 timespec (16 B) Letzte Änderung
STAT_CTIME 104 timespec (16 B) Letzte Metadatenänderung

Zugriffsmodus-Flags

Konstante Wert Beschreibung
F_OK 0 Datei existiert
R_OK 4 Lesbar
W_OK 2 Schreibbar
X_OK 1 Ausführbar

iovec / Pfad

Konstante Wert Beschreibung
IOVEC_SIZE 16 Größe eines iovec-Eintrags ({base: int64, len: int64})
PATH_MAX 4096 Maximale Pfadlänge in Bytes (für GetCwd)

Funktionen

Datei-Metadaten

Signatur Beschreibung
Fstat(fd: int64, statBuf: int64): int64 Füllt statBuf (alloc(STAT_SIZE)) mit den Metadaten des geöffneten fd. Gibt 0 bei Erfolg zurück
StatFileSize(statBuf: int64): int64 Dateigröße in Bytes (Offset STAT_SIZE_F)
StatMtime(statBuf: int64): int64 Zeitstempel der letzten Änderung in Nanosekunden
StatMode(statBuf: int64): int64 Zugriffsrechte (12 Bits, z. B. 0644 = 420)
StatIsDir(statBuf: int64): bool Gibt true zurück wenn der fd ein Verzeichnis ist
StatIsFile(statBuf: int64): bool Gibt true zurück wenn der fd eine reguläre Datei ist
FileSize(path: pchar): int64 Öffnet path, liest die Dateigröße via Fstat und schließt sofort wieder. Gibt -1 bei Fehler zurück

Positioniertes Lesen / Schreiben

Signatur Beschreibung
PRead(fd: int64, buf: int64, n: int64, off: int64): int64 Liest n Bytes aus fd ab Position off — ändert den fd-Offset nicht
PWrite(fd: int64, buf: int64, n: int64, off: int64): int64 Schreibt n Bytes in fd an Position off — ändert den fd-Offset nicht

Scatter-Gather-I/O (iovec)

Signatur Beschreibung
IovecSet(buf: int64, idx: int64, base: int64, len: int64) Setzt buf[idx] = { base, len } (alloc(IOVEC_SIZE * count))
IovecBase(buf: int64, idx: int64): int64 Liest den base-Zeiger von buf[idx]
IovecLen(buf: int64, idx: int64): int64 Liest die Länge von buf[idx]
ReadV(fd: int64, iov: int64, iovcnt: int64): int64 Liest von fd in mehrere Puffer auf einmal (scatter)
WriteV(fd: int64, iov: int64, iovcnt: int64): int64 Schreibt mehrere Puffer in einem Syscall in fd (gather)

Zugriffsprüfung

Signatur Beschreibung
FileAccess(path: pchar, mode: int64): bool Gibt true zurück wenn path den angegebenen Modus (F_OK / R_OK / W_OK / X_OK) hat
FileExists(path: pchar): bool Gibt true zurück wenn path existiert
FileReadable(path: pchar): bool Gibt true zurück wenn path lesbar ist
FileWritable(path: pchar): bool Gibt true zurück wenn path schreibbar ist

Synchronisierung

Signatur Beschreibung
Fsync(fd: int64): int64 Schreibt Daten und Metadaten des fd vollständig auf das Speichermedium
Fdatasync(fd: int64): int64 Wie Fsync, aber ohne Metadaten-Update (schneller)

Dateigröße ändern

Signatur Beschreibung
Truncate(path: pchar, length: int64): int64 Setzt die Größe von path auf length Bytes (kein offener fd nötig)
Ftruncate(fd: int64, length: int64): int64 Wie Truncate, aber über offenen fd

Arbeitsverzeichnis

Signatur Beschreibung
GetCwd(buf: int64, size: int64): int64 Schreibt das aktuelle Verzeichnis in buf (alloc(PATH_MAX)). Gibt Länge zurück oder < 0
Chdir(path: pchar): int64 Wechselt das Arbeitsverzeichnis des Prozesses

Kernelseitiger Dateitransfer

Signatur Beschreibung
Sendfile(outFd: int64, inFd: int64, offsetPtr: int64, count: int64): int64 Überträgt count Bytes von inFd nach outFd ohne Userspace-Kopie. offsetPtr: Zeiger auf int64 (Leseposition) oder 0 für aktuellen fd-Offset. Gibt übertragene Bytes zurück

Verwendung

Datei-Metadaten lesen

import std.fs_ext;
import std.fs;
import std.alloc;
import std.io;

fn PrintFileMeta(path: pchar): void {
    var fd := open(path, 0, 0);   // O_RDONLY
    if (fd < 0) { return; }

    var stat: int64 := alloc(STAT_SIZE);
    Fstat(fd, stat);

    PrintLn("Größe: " + IntToStr(StatFileSize(stat)) + " Bytes");

    Print("Ist Verzeichnis: ");
    if (StatIsDir(stat)) { Print("ja\n"); } else { Print("nein\n"); }

    free(stat, STAT_SIZE);
    close(fd);
}

Positioniertes Lesen (parallele Threads)

import std.fs_ext;
import std.alloc;

// Verschiedene Threads können denselben fd lesen ohne lseek-Konflikte.
fn ReadChunk(fd: int64, offset: int64, size: int64): int64 {
    var buf: int64 := alloc(size);
    var n := PRead(fd, buf, size, offset);
    // Puffer verarbeiten...
    free(buf, size);
    return n;
}

Scatter-Gather: Header + Body in einem Syscall

import std.fs_ext;
import std.alloc;

fn SendHeaderAndBody(fd: int64, header: int64, hLen: int64,
                                body: int64,   bLen: int64): void {
    var iov: int64 := alloc(IOVEC_SIZE * 2);
    IovecSet(iov, 0, header, hLen);
    IovecSet(iov, 1, body,   bLen);
    WriteV(fd, iov, 2);
    free(iov, IOVEC_SIZE * 2);
}

Sendfile: statische Datei ausliefern

import std.fs_ext;
import std.fs;
import std.alloc;

fn ServeFile(socketFd: int64, path: pchar): void {
    var fd  := open(path, 0, 0);
    if (fd < 0) { return; }

    var stat: int64 := alloc(STAT_SIZE);
    Fstat(fd, stat);
    var size := StatFileSize(stat);
    free(stat, STAT_SIZE);

    // Kernel überträgt direkt ohne Userspace-Kopie
    Sendfile(socketFd, fd, 0, size);
    close(fd);
}


Hinweise

  • PRead/PWrite sind thread-sicher: Mehrere Threads können denselben fd mit unterschiedlichen Offsets benutzen.
  • Sendfile funktioniert nur wenn outFd ein Socket oder regulärer fd ist — nicht für Pipes.
  • Truncate kann eine Datei auch vergrößern; der neue Bereich wird mit Null-Bytes gefüllt.
  • StatMtime liefert einen timespec-Wert in Nanosekunden — für Sekunden durch 1000000000 teilen.
  • FileAccess prüft den effektiven Benutzer (EUID), nicht den realen (UID).

Verwandte Units

Letzte Aktualisierung: 2026-06-05