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

Функция fstat: получение данных о файле в PHP
Раздел: Работа с файловой системой
fstat(resource $stream): array|false
Назначение и аргументы fstat

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

Использование актуально, когда файл уже открыт функциями fopen(), fsockopen() или popen(), и требуется получить данные (размер, время модификации, права доступа) без повторного обращения к файловой системе.

Аргумент у функции один:

  • $stream (resource) - Корректный файловый указатель, полученный после успешного открытия файла.

Функция возвращает:

  • Ассоциативный или числовой массив со статистикой (формат зависит от контекста вызова) при успехе.
  • false в случае возникновения ошибки.

Структура возвращаемого массива содержит индексы, такие как: dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, blocks.

Базовые примеры использования
Получение информации о файле
<?php
$fp = fopen('example.txt', 'r');
$stat = fstat($fp);
fclose($fp);
print_r($stat);
?>
Array
(
    [0] => 2050
    [1] => 1234567
    [2] => 33188
    [3] => 1
    [4] => 1000
    [5] => 1000
    [6] => 0
    [7] => 1024
    [8] => 1678900000
    [9] => 1678910000
    [10] => 1678920000
    [11] => 4096
    [12] => 2
    [dev] => 2050
    [ino] => 1234567
    [mode] => 33188
    [nlink] => 1
    [uid] => 1000
    [gid] => 1000
    [rdev] => 0
    [size] => 1024
    [atime] => 1678900000
    [mtime] => 1678910000
    [ctime] => 1678920000
    [blksize] => 4096
    [blocks] => 2
)
Выборочный доступ к данным
<?php
$fp = fopen('data.log', 'r');
$stat = fstat($fp);
echo "Размер файла: ".$stat['size']." байт";
echo "\nВремя изменения: ".date('Y-m-d H:i:s', $stat['mtime']);
fclose($fp);
?>
Размер файла: 524288 байт
Время изменения: 2023-03-15 14:30:25
Похожие функции в PHP

stat(string $filename): работает с именем файла, а не с указателем. Требует повторного доступа к файловой системе. Предпочтительна, когда файл не открыт.

lstat(string $filename): аналогична stat(), но для символических ссылок возвращает информацию о самой ссылке, а не о целевом файле.

filesize(), filemtime(), fileperms(): функции для получения конкретных атрибутов. Их вызов эффективнее, если нужен только один параметр, а не вся статистика.

SplFileInfo: объектно-ориентированный подход (getSize(), getMTime(), getPerms()). Удобен в современном коде и предоставляет больше методов для работы с путями.

Типичные ошибки
Передача некорректного ресурса
<?php
$fp = false; // Не файловый указатель
$stat = fstat($fp);
var_dump($stat);
?>
Warning: fstat() expects parameter 1 to be resource, bool given
bool(false)
Использование закрытого указателя
<?php
$fp = fopen('temp.txt', 'w');
fclose($fp);
$stat = fstat($fp); // $fp уже закрыт
?>
Warning: fstat(): supplied resource is not a valid stream resource
Работа с несуществующим потоком
<?php
$fp = fopen('https://example.com', 'r'); // Предположим, ошибка сети
if($fp) {
    $stat = fstat($fp); // Может не сработать для некоторых сетевых потоков
}
?>
Изменения в PHP 8

В PHP 8 поведение fstat() для буферированных потоков стало более последовательным. Ранее при работе с некоторыми обёртками потоков (например, php://memory) функция могла возвращать данные с задержкой или некорректно. В восьмой версии эти проблемы устранены.

Сигнатура функции не изменилась. Типизация аргументов стала строже из-за внутренних изменений в обработке ресурсов.

Расширенные примеры
Мониторинг изменения размера файла
Пример php
<?php
$fp = fopen('growing.log', 'r');
$lastSize = 0;
while(true) {
    $stat = fstat($fp);
    if($stat['size'] > $lastSize) {
        echo "Файл вырос: ".$stat['size']." байт\n";
        $lastSize = $stat['size'];
        fseek($fp, $lastSize); // Переместить указатель в конец
    }
    sleep(1);
}
// fclose($fp); // В реальном коде нужно предусмотреть остановку
?>
Проверка, является ли ресурс файлом
Пример php
<?php
function isRegularFile($stream) {
    $stat = fstat($stream);
    return ($stat['mode'] & 0xF000) === 0x8000; // Проверка битового поля S_IFREG
}
$fp = fopen('/dev/null', 'r');
var_dump(isRegularFile($fp));
fclose($fp);
?>
bool(false)
Сравнение времени модификации двух файлов
Пример php
<?php
$fp1 = fopen('file1.txt', 'r');
$fp2 = fopen('file2.txt', 'r');
$stat1 = fstat($fp1);
$stat2 = fstat($fp2);
if($stat1['mtime'] > $stat2['mtime']) {
    echo "file1.txt новее";
}
fclose($fp1);
fclose($fp2);
?>
Получение информации о стандартном потоке ввода
Пример php
<?php
$stdin = fopen('php://stdin', 'r');
$stat = fstat($stdin);
print_r($stat['size']); // Для потоков размер может быть 0 или неактуален
fclose($stdin);
?>
Аналоги в других языках
Python: os.fstat()
import os
f = open('file.txt', 'r')
stat_info = os.fstat(f.fileno())
print(f"Размер: {stat_info.st_size}")
print(f"Inode: {stat_info.st_ino}")
f.close()
Размер: 1024
Inode: 1234567
JavaScript (Node.js): fs.fstat()
const fs = require('fs');
fs.open('file.txt', 'r', (err, fd) => {
  fs.fstat(fd, (err, stats) => {
    console.log(`Размер: ${stats.size}`);
    fs.close(fd, () => {});
  });
});
MySQL: STATISTICS

Прямого аналога для файлов нет. Информацию о таблицах можно получить через системную таблицу INFORMATION_SCHEMA.STATISTICS.

PHP fstat function comments

En
Fstat Gets information about a file using an open file pointer