fseek()
Die PHP-Funktion fseek() setzt den Dateipositionszeiger für einen Datei-Pointer. Hier erfahren Sie Syntax, Modus und Praxisbeispiele.
Wenn PHP eine Datei liest oder schreibt, hält es intern einen Cursor — den Dateipositionszeiger — der markiert, wo der nächste Lese- oder Schreibvorgang stattfindet. Normalerweise bewegt sich dieser Cursor automatisch vorwärts, wenn Sie fread() oder fwrite() aufrufen. Die Funktion fseek() ermöglicht es, ihn manuell an eine beliebige Byte-Position zu verschieben, sodass Sie rückwärts springen, vorwärts überspringen oder einen Teil einer Datei erneut lesen können, ohne sie zu schließen und neu zu öffnen.
Dieses Kapitel behandelt die Syntax von fseek(), die drei whence-Modi, den Rückgabewert sowie praktische Muster wie das Lesen eines Datensatzes an einem bekannten Offset und das Suchen über das Dateiende hinaus.
Syntax
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int| Parameter | Beschreibung |
|---|---|
$stream | Ein Datei-Pointer, der von fopen() zurückgegeben wurde. |
$offset | Die Anzahl der zu verschiebenden Bytes. Kann mit SEEK_CUR und SEEK_END negativ sein. |
$whence | Der Referenzpunkt, von dem aus der Offset gemessen wird. Standardmäßig SEEK_SET. |
fseek() gibt bei Erfolg 0 und bei Fehler -1 zurück. Es gibt nicht die neue Position zurück — verwenden Sie dafür ftell().
Die drei whence-Modi
Die Konstante $whence legt fest, von wo aus der Offset gezählt wird:
| Konstante | Resultierende Position |
|---|---|
SEEK_SET | offset Bytes vom Anfang der Datei (der Standard). |
SEEK_CUR | offset Bytes von der aktuellen Position. |
SEEK_END | offset Bytes vom Ende der Datei. Verwenden Sie einen negativen Offset, um zurückzugehen. |
<?php
fseek($file, 10); // 10 bytes from the start (SEEK_SET is implied)
fseek($file, 5, SEEK_CUR); // 5 bytes forward from where we are now
fseek($file, -4, SEEK_END); // 4 bytes before the end of the fileEin funktionierendes Beispiel
Lassen Sie uns eine Datei erstellen, dann zu Byte 6 springen und von dort lesen. Da wir im selben Skript schreiben und lesen, ist das Beispiel vollständig in sich geschlossen:
<?php
$filename = 'demo.txt';
// Create a file with known contents.
file_put_contents($filename, 'Hello, World!');
$file = fopen($filename, 'r');
fseek($file, 7, SEEK_SET); // move the cursor to byte 7
$data = fread($file, 5); // read 5 bytes: W, o, r, l, d
echo $data; // World
fclose($file);Der string 'Hello, World!' wird als Bytes H(0) e(1) l(2) l(3) o(4) ,(5) (6) W(7) o(8) r(9) l(10) d(11) !(12) gespeichert. Ein Sprung zu Byte 7 landet auf dem W, und das Lesen von 5 Bytes gibt World aus.
Immer den Rückgabewert prüfen
Da fseek() bei Erfolg 0 und bei Fehler -1 zurückgibt, sollten Sie explizit vergleichen. Eine lockere Wahrheitswertprüfung ist hier falsch — 0 ist falsy:
<?php
$file = fopen('demo.txt', 'r');
if (fseek($file, 7) === -1) {
echo "Seek failed";
} else {
echo "Seek succeeded"; // Seek succeeded
}
fclose($file);Wichtige Hinweise
- Nicht jeder Stream ist suchbar. Pipes, Netzwerk-Sockets und der
php://stdin-Stream können nicht gesucht werden;fseek()gibt bei ihnen-1zurück. - Das Suchen über das Dateiende hinaus ist erlaubt. Bei einer zum Schreiben geöffneten Datei können Sie mit
fseek()über das aktuelle Ende hinausgehen und dann schreiben — die Lücke wird mit\0-(null-)Bytes gefüllt und erzeugt so einen dünn besetzten Bereich. - Vorsicht bei
SEEK_CURim Append-Modus. Dateien, die mit dem Modus'a'geöffnet wurden, schreiben immer am Ende, unabhängig vom Cursor;fseek()beeinflusst in diesem Modus nur Lesevorgänge. fseek()löscht das End-of-File-Flag, sodass Sie durch Zurücksuchen Daten lesen können, die Sie bereits passiert haben, ohne die Datei neu zu öffnen.
Verwandte Funktionen
ftell()— gibt die aktuelle Cursor-Position zurück (das Gegenstück zufseek()).rewind()— Abkürzung fürfseek($file, 0).fread()/fwrite()— ab dem Cursor lesen oder schreiben.fopen()/fclose()— den Stream öffnen und schließen.
Weitere Informationen finden Sie im Kapitel PHP File Handling.
Fazit
fseek() ermöglicht wahlfreien Zugriff auf eine Datei: Verschieben Sie den Cursor mit einem $offset, gemessen von SEEK_SET, SEEK_CUR oder SEEK_END, und lesen oder schreiben Sie dann ab der neuen Position. Denken Sie daran, auf den Rückgabewert -1 zu prüfen, kombinieren Sie die Funktion mit ftell(), um die aktuelle Position zu kennen, und beachten Sie, dass nicht jeder Stream das Suchen unterstützt.