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
| 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
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
std.fs — Basis-Datei-I/O (open, read, write, close, mkdir …)
-
-
-
Letzte Aktualisierung: 2026-06-05