Fseek: примеры (PHP)

Функция fseek в PHP: руководство с практическими примерами
Раздел: Работа с файлами
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int

Функция fseek в PHP

Назначение и применение

Функция fseek() предназначена для перемещения указателя позиции в открытом файловом потоке. Она используется при работе с бинарными и текстовыми файлами для произвольного доступа к данным, позволяя читать или записывать информацию с конкретной позиции без обработки всего файла.

Аргументы функции
  • stream (обязательный): Ресурс файлового потока, полученный с помощью функции fopen().
  • offset (обязательный): Количество байт для смещения указателя. Может быть положительным (смещение вперёд), отрицательным (смещение назад) или нулевым.
  • whence (необязательный): Константа, определяющая точку отсчёта смещения:
    • SEEK_SET (значение 0) - отсчёт от начала файла (используется по умолчанию).
    • SEEK_CUR (значение 1) - отсчёт от текущей позиции указателя.
    • SEEK_END (значение 2) - отсчёт от конца файла.

Функция возвращает 0 при успешном выполнении и -1 в случае ошибки.

Базовые примеры использования

Чтение с середины файла
<?php
$fp = fopen('test.txt', 'r');
fseek($fp, 10); // Указатель на 11-й байт (отсчёт с 0)
echo fread($fp, 5);
fclose($fp);
?>
World
Смещение от текущей позиции
<?php
$fp = fopen('data.bin', 'rb');
fread($fp, 5); // Читаем 5 байт, указатель смещается
fseek($fp, 3, SEEK_CUR); // Смещаемся ещё на 3 байта вперёд
echo ftell($fp); // Текущая позиция
fclose($fp);
?>
8
Смещение от конца файла
<?php
$fp = fopen('log.txt', 'r');
fseek($fp, -20, SEEK_END); // Последние 20 байт файла
echo fread($fp, 20);
fclose($fp);
?>
2024-01-15: завершение
Похожие функции в PHP

Определяет текущую позицию указателя в файле. Часто используется совместно с fseek() для запоминания позиции.

Сбрасывает указатель файла в начало. Эквивалентна fseek($fp, 0).

fgetc(), fgets(), fread()

Функции чтения, автоматически продвигающие указатель. При необходимости произвольного доступа комбинируются с fseek().

file_get_contents() и file_put_contents()

Чтение/запись всего файла без управления указателем. Подходят для работы с небольшими файлами целиком.

SplFileObject

Класс объектно-ориентированного интерфейса для файлов с методами fseek(), ftell(), rewind(). Рекомендуется для сложных операций с файлами.

Аналоги в других языках

Fseek в Python

Метод seek() у файловых объектов. Аналогичен fseek, но принимает только два аргумента.

with open('test.txt', 'rb') as f:
    f.seek(10)
    print(f.read(5).decode())
World
JavaScript (Node.js)

Метод fs.createReadStream() с опцией start или использование fs.open() с fs.read(). Прямого аналога нет, позиционирование реализуется через параметры чтения.

const fs = require('fs');
fs.open('test.txt', 'r', (err, fd) => {
    const buffer = Buffer.alloc(5);
    fs.read(fd, buffer, 0, 5, 10, (err, bytes) => {
        console.log(buffer.toString());
    });
});
World

Fseek в MySQL

Функция SEEK в составе обработчиков файлов или использование предложения LIMIT со смещением для постраничного вывода, но не для прямого доступа к файлам.

C/C++

Функция fseek() стандартной библиотеки, послужившая прототипом для PHP. Имеет идентичную семантику.

Типичные ошибки
Попытка смещения за пределы файла
<?php
$fp = fopen('small.txt', 'r');
$result = fseek($fp, 1000);
if ($result === -1) {
    echo "Ошибка позиционирования";
}
fclose($fp);
?>
Ошибка позиционирования
Работа с закрытым потоком
<?php
$fp = fopen('test.txt', 'r');
fclose($fp);
fseek($fp, 0);
?>
Warning: fseek(): supplied resource is not a valid stream resource
Использование с недопустимым режимом открытия

При открытии файла в режиме 'a' (дописывание) функция fseek не может переместить указатель записи.

<?php
$fp = fopen('log.txt', 'a');
fseek($fp, 0); // Указатель чтения сместится, но запись всегда в конец
echo ftell($fp);
fwrite($fp, "test"); // Запись произойдёт в конец файла
fclose($fp);
?>
0
Изменения в новых версиях PHP
PHP 7.0

Функция возвращает -1 вместо 0 при ошибке позиционирования за пределами файла.

PHP 8.0

Типы параметров стали строгими. Некорректные типы аргументов вызывают TypeError.

<?php
$fp = fopen('test.txt', 'r');
// fseek($fp, 'string'); // Вызовет TypeError в PHP 8
fclose($fp);
?>
TypeError: fseek(): Argument #2 ($offset) must be of type int, string given

Расширенные примеры

Модификация бинарного файла
Пример php
<?php
$filename = 'data.bin';
$fp = fopen($filename, 'r+b'); // Чтение и запись, бинарный режим
fseek($fp, 4);
fwrite($fp, pack('C', 0xFF)); // Замена пятого байта
fclose($fp);
?>
Построчное чтение с конца
Пример php
<?php
function readLastLines($filename, $lines) {
    $fp = fopen($filename, 'r');
    fseek($fp, 0, SEEK_END);
    $pos = ftell($fp);
    $buffer = '';
    $lineCount = 0;
    while ($lineCount < $lines && $pos > 0) {
        $pos--;
        fseek($fp, $pos);
        $char = fread($fp, 1);
        if ($char === "\n") $lineCount++;
        $buffer = $char . $buffer;
    }
    fclose($fp);
    return $buffer;
}
echo readLastLines('large.log', 5);
?>
Создание файла с "дырками"
Пример php
<?php
$fp = fopen('sparse.bin', 'wb');
fwrite($fp, 'start');
fseek($fp, 1024 * 1024, SEEK_CUR); // Пропуск 1 МБ
fwrite($fp, 'end');
fclose($fp);
echo filesize('sparse.bin');
?>
1048582
Индексный доступ к CSV
Пример php
<?php
// Предполагается, что индекс позиций создан ранее
$index = [0 => 0, 1 => 150, 2 => 300];
$fp = fopen('data.csv', 'r');
fseek($fp, $index[2]); // Прямой переход к третьей записи
echo fgets($fp); // Чтение строки
fclose($fp);
?>
Обработка запакованных данных
Пример php
<?php
$fp = fopen('packed.dat', 'rb');
fseek($fp, 8); // Пропуск первых 8 байт заголовка
$data = fread($fp, 4);
$value = unpack('V', $data)[1]; // Чтение 32-битного беззнакового целого
echo $value;
fclose($fp);
?>

PHP fseek function comments

En
Fseek Seeks on a file pointer