How does PHP fstat() function work?

547 Views Asked by At

How does PHP fstat() function work?

Does the function read file size from disk on every call?

Or does the function calculate the size based on all writing operations performed?

Example:

$filename='abc.txt';

$fp=fopen($filename, 'a');

$fstat=fstat($fp);
echo 'Size: '.$fstat['size'].'<br><br>';

echo 'Writing...<br><br>';
fwrite($fp, 'xx');
fwrite($fp, 'yyyy');
// ...
// Some number of fwrite() opertions
// ...
fwrite($fp, 'zzzzzz');

$fstat=fstat($fp);
echo 'Size after writing: '.$fstat['size'].'<br>';
// Does the size is read from disk or is calculated based on earlier writing operations?

fclose($fp);
2

There are 2 best solutions below

0
Mark Setchell On

I suspect you are asking because the size is not as you expect. And I suspect it is not as you expect because you read the size before closing the file when some writes are still buffered.

Try closing the file first and then using stat():

$filename='abc.txt';
$fp=fopen($filename, 'a');

$fstat=fstat($fp);
fwrite($fp, 'xx');
fwrite($fp, 'yyyy');
...
...
fclose($fp);


$stat=stat($filename);
echo 'Size after writing: '.$stat['size'].'<br>';
2
Kinga the Witch On

After some tests I think the function fstat() calculates the size because it is much more faster than filesize() with clearstatcache().

The code:

for (/*loop for 10 000 files*/) {
    fwrite($fp, '123');
    $fstat=fstat($fp);
    fwrite($fp, '123');
    $fstat=fstat($fp);
    fwrite($fp, '123');
    $fstat=fstat($fp);
}

is similar (in preformance) to:

// Here filesize() is BUFFERED and gives wrong results
for (/*loop for 10 000 files*/) {
    fwrite($fp, '123');
    $fsize=filesize($filename);

    fwrite($fp, '123');
    $fsize=filesize($filename);

    fwrite($fp, '123');
    $fsize=filesize($filename);
}

is faster than:

// Here filesize() reads size on every call
for (/*loop for 10 000 files*/) {
    fwrite($fp, '123');
    clearstatcache();
    $fsize=filesize($filename);

    fwrite($fp, '123');
    clearstatcache();
    $fsize=filesize($filename);

    fwrite($fp, '123');
    clearstatcache();
    $fsize=filesize($filename);
}

and than:

// Here filesize() reads size on every call
for (/*loop for 10 000 files*/) {
    fwrite($fp, '123');
    clearstatcache(true, $filename);
    $fsize=filesize($filename);

    fwrite($fp, '123');
    clearstatcache(true, $filename);
    $fsize=filesize($filename);

    fwrite($fp, '123');
    clearstatcache(true, $filename);
    $fsize=filesize($filename);
}