Start · Sprachen · PHP · Referenz · eio_fallocate

eio_fallocate

Funktion

Ermöglicht die direkte Manipulation des zugewiesenen Speicherplatzes einer Datei mittels des POSIX-Systemaufrufs <code>fallocate()</code>.

seit PHP 0.0.1 Kategorie: io

Signatur

eio_fallocate(mixed $fd, int $mode, int $offset, int $length, int $pri = EIO_PRI_DEFAULT, callable $callback = null, mixed $data = null): resource

Beschreibung

eio_fallocate() ist Teil der EIO-Erweiterung (asynchrone POSIX-I/O-Operationen) und bietet eine nicht-blockierende Schnittstelle zum Systemaufruf fallocate(2). Damit lässt sich Speicherplatz für eine Datei vorab reservieren oder freigeben, ohne dass explizit Daten geschrieben werden müssen.

Dies ist besonders nützlich, wenn eine Anwendung weiß, wie groß eine Datei werden wird, und das Dateisystem vorab informieren möchte, um Fragmentierung zu vermeiden und die Schreibperformance zu verbessern. Typische Anwendungsfälle sind Download-Manager, Media-Streaming-Server oder Datenbank-Backends.

Der Parameter mode steuert das Verhalten: Mit dem Wert 0 wird Speicherplatz reserviert und die Dateigröße angepasst. Mit FALLOC_FL_KEEP_SIZE wird Speicherplatz reserviert, ohne die sichtbare Dateigröße zu ändern. Mit FALLOC_FL_PUNCH_HOLE kann ein Lochbereich (Sparse File) erzeugt werden, um Speicherplatz freizugeben.

Da eio_fallocate() asynchron arbeitet, kehrt die Funktion sofort zurück und liefert eine Ressource. Das Ergebnis der Operation wird über die $callback-Funktion gemeldet, sobald die Operation abgeschlossen ist. Die EIO-Ereignisschleife muss z. B. mit eio_event_loop() laufen gelassen werden.

Parameter

Name Typ Default Beschreibung
$fd Pflicht mixed Ein gültiger Dateideskriptor, der mit eio_open() oder einer anderen geeigneten Funktion geöffnet wurde.
$mode Pflicht int Steuert das Allokationsverhalten. 0 reserviert Speicherplatz und passt die Dateigröße an. Konstanten wie FALLOC_FL_KEEP_SIZE oder FALLOC_FL_PUNCH_HOLE sind je nach Systemunterstützung verfügbar.
$offset Pflicht int Startposition (in Bytes) innerhalb der Datei, ab der die Speichermanipulation beginnen soll.
$length Pflicht int Anzahl der Bytes, die ab $offset reserviert oder freigegeben werden sollen.
$pri int EIO_PRI_DEFAULT Priorität der asynchronen Operation. Mögliche Werte: EIO_PRI_DEFAULT, EIO_PRI_MIN, EIO_PRI_MAX.
$callback callable null Callback-Funktion, die nach Abschluss der Operation aufgerufen wird. Signatur: function(mixed $data, int $result, resource $req): void. $result ist 0 bei Erfolg, ansonsten -1.
$data mixed null Beliebige benutzerdefinierte Daten, die unverändert an den Callback übergeben werden.

Rückgabewert

Typ
resource
Beschreibung
Gibt eine EIO-Anfrage-Ressource zurück, wenn die Operation erfolgreich in die Warteschlange eingereiht wurde, oder false bei einem Fehler.

Beispiele

Speicherplatz für eine neue Datei vorab reservieren

<?php
// EIO-Erweiterung voraussetzen
$tmpFile = tempnam(sys_get_temp_dir(), 'eio_');

// Datei asynchron öffnen
eio_open(
    $tmpFile,
    EIO_O_RDWR | EIO_O_CREAT,
    0644,
    EIO_PRI_DEFAULT,
    function ($data, $result, $req) use ($tmpFile) {
        if ($result < 0) {
            echo 'Fehler beim Öffnen der Datei.' . PHP_EOL;
            return;
        }
        $fd = $result;

        // 1 MB (1048576 Bytes) ab Offset 0 vorab reservieren
        eio_fallocate(
            $fd,
            0,       // Standard-Modus: Speicher reservieren + Größe anpassen
            0,       // Offset
            1048576, // Länge: 1 MB
            EIO_PRI_DEFAULT,
            function ($data, $result, $req) use ($fd, $tmpFile) {
                if ($result === 0) {
                    echo '1 MB Speicherplatz erfolgreich reserviert.' . PHP_EOL;
                } else {
                    echo 'Fehler bei eio_fallocate: ' . eio_get_last_error($req) . PHP_EOL;
                }
                eio_close($fd);
            },
            null
        );
    },
    null
);

eio_event_loop();
unlink($tmpFile);
1 MB Speicherplatz erfolgreich reserviert.

Speicherplatz reservieren ohne sichtbare Größenänderung (KEEP_SIZE)

<?php
$tmpFile = tempnam(sys_get_temp_dir(), 'eio_keep_');

eio_open(
    $tmpFile,
    EIO_O_RDWR | EIO_O_CREAT,
    0644,
    EIO_PRI_DEFAULT,
    function ($data, $fd, $req) use ($tmpFile) {
        if ($fd < 0) {
            echo 'Öffnen fehlgeschlagen.' . PHP_EOL;
            return;
        }

        // FALLOC_FL_KEEP_SIZE = 1: Dateigröße bleibt 0, aber Blöcke werden reserviert
        $FALLOC_FL_KEEP_SIZE = 1;

        eio_fallocate(
            $fd,
            $FALLOC_FL_KEEP_SIZE,
            0,
            512 * 1024, // 512 KB
            EIO_PRI_DEFAULT,
            function ($data, $result, $req) use ($fd, $tmpFile) {
                $size = filesize($tmpFile);
                echo 'Sichtbare Dateigröße nach KEEP_SIZE-Allokation: ' . $size . ' Bytes' . PHP_EOL;
                // Erwartet: 0 Bytes, da KEEP_SIZE die sichtbare Größe nicht ändert
                eio_close($fd);
            },
            null
        );
    },
    null
);

eio_event_loop();
unlink($tmpFile);
Sichtbare Dateigröße nach KEEP_SIZE-Allokation: 0 Bytes

// Wichtig · Fallstricke

Plattformabhängigkeit: eio_fallocate() setzt den Linux-Systemaufruf fallocate(2) voraus. Auf macOS und anderen BSD-Systemen ist diese Funktion unter Umständen nicht verfügbar oder verhält sich anders. Die Verfügbarkeit hängt auch vom eingesetzten Dateisystem ab (ext4, XFS etc. unterstützen fallocate vollständig, FAT32 oder NFS nicht zwingend).

Fehlerbehandlung: Der Rückgabewert $result im Callback ist 0 bei Erfolg und -1 bei Fehler. Mit eio_get_last_error($req) lässt sich die Fehlermeldung auslesen.

EIO-Ereignisschleife: Damit der Callback ausgeführt wird, muss die EIO-Ereignisschleife laufen (eio_event_loop() oder Integration in libevent/libev). Ohne die Schleife bleibt die Operation in der Warteschlange hängen.