fseek()
Функция fseek() в PHP перемещает указатель позиции файла. Узнайте о режимах whence, возвращаемых значениях и практических примерах.
Когда PHP читает или записывает файл, он поддерживает внутренний курсор — указатель позиции файла — который отмечает место следующего чтения или записи. Обычно этот курсор перемещается вперёд автоматически при вызове fread() или fwrite(). Функция fseek() позволяет перемещать его вручную на любую байтовую позицию: переходить назад, перепрыгивать вперёд или повторно читать часть файла без закрытия и повторного открытия.
В этой главе рассматриваются синтаксис fseek(), три режима whence, возвращаемое значение и практические приёмы — например, чтение записи по известному смещению и перемещение курсора за конец файла.
Синтаксис
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int| Параметр | Описание |
|---|---|
$stream | Указатель файла, возвращённый fopen(). |
$offset | Количество байт для перемещения. Может быть отрицательным при SEEK_CUR и SEEK_END. |
$whence | Точка отсчёта, от которой измеряется смещение. По умолчанию — SEEK_SET. |
fseek() возвращает 0 при успехе и -1 при ошибке. Функция не возвращает новую позицию — используйте ftell() для этого.
Три режима whence
Константа $whence определяет, от какой точки отсчитывается смещение:
| Константа | Результирующая позиция |
|---|---|
SEEK_SET | offset байт от начала файла (по умолчанию). |
SEEK_CUR | offset байт от текущей позиции. |
SEEK_END | offset байт от конца файла. Используйте отрицательное смещение для движения назад. |
<?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 fileПрактический пример
Создадим файл, затем перейдём к байту 6 и прочитаем данные оттуда. Поскольку запись и чтение происходят в одном скрипте, пример полностью автономен:
<?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);Строка 'Hello, World!' хранится как байты H(0) e(1) l(2) l(3) o(4) ,(5) (6) W(7) o(8) r(9) l(10) d(11) !(12). Переход к байту 7 устанавливает курсор на W, а чтение 5 байт выводит World.
Всегда проверяйте возвращаемое значение
Поскольку fseek() возвращает 0 при успехе и -1 при ошибке, сравнивайте явно. Проверка на истинность здесь неверна — 0 является ложным значением:
<?php
$file = fopen('demo.txt', 'r');
if (fseek($file, 7) === -1) {
echo "Seek failed";
} else {
echo "Seek succeeded"; // Seek succeeded
}
fclose($file);На что обратить внимание
- Не каждый поток поддерживает поиск. Каналы, сетевые сокеты и поток
php://stdinне поддерживают поиск;fseek()возвращает-1для них. - Перемещение за конец файла разрешено. При открытии файла для записи можно вызвать
fseek()за текущий конец и затем писать — промежуток заполняется байтами\0(null), создавая разреженную область. - Осторожно с
SEEK_CURв режиме дозаписи. Файлы, открытые в режиме'a', всегда пишут в конец независимо от положения курсора;fseek()влияет только на операции чтения в этом режиме. fseek()сбрасывает флаг конца файла, поэтому возврат назад позволяет читать уже пройденные данные без повторного открытия файла.
Связанные функции
ftell()— сообщает текущую позицию курсора (дополнение кfseek()).rewind()— сокращение дляfseek($file, 0).fread()/fwrite()— чтение или запись начиная с позиции курсора.fopen()/fclose()— открытие и закрытие потока.
Смотрите главу PHP File Handling для общего понимания темы.
Заключение
fseek() предоставляет произвольный доступ к файлу: перемещайте курсор с помощью $offset, отсчитываемого от SEEK_SET, SEEK_CUR или SEEK_END, затем читайте или пишите с новой позиции. Не забывайте проверять возвращаемое значение -1, используйте ftell(), чтобы знать текущую позицию, и помните, что не каждый поток поддерживает поиск.