PHP 5.4.36 Released

filesize

(PHP 4, PHP 5)

filesizeLit la taille d'un fichier

Description

int filesize ( string $filename )

Lit la taille du fichier donné.

Liste de paramètres

filename

Chemin vers le fichier.

Valeurs de retour

Renvoie la taille du fichier filename en octets, ou FALSE (et génère une erreur de niveau E_WARNING) en cas d'erreur.

Note: Comme le type entier de PHP est signé et que de nombreuses plates-formes utilisent des entiers de 32 bits, certaines fonctions relatives au système de fichiers peuvent retourner des résultats étranges pour les fichiers de taille supérieure à 2 Go.

Exemples

Exemple #1 Exemple avec filesize()

<?php

// Affiche e.g.  somefile.txt: 1024 bytes

$filename 'somefile.txt';
echo 
$filename ': ' filesize($filename) . ' bytes';

?>

Erreurs / Exceptions

En cas d'échec, une alerte de type E_WARNING sera émise.

Notes

Note: Les résultats de cette fonction sont mis en cache. Voyez la fonction clearstatcache() pour plus de détails.

Astuce

Depuis PHP 5.0.0, cette fonction peut aussi être utilisée avec quelques protocoles url. Lisez Liste des protocoles et des gestionnaires supportés pour connaître les protocoles supportant la famille de fonctionnalités de stat().

Voir aussi

add a note add a note

User Contributed Notes 19 notes

up
54
rommel at rommelsantor dot com
3 years ago
Extremely simple function to get human filesize.
<?php
function human_filesize($bytes, $decimals = 2) {
 
$sz = 'BKMGTP';
 
$factor = floor((strlen($bytes) - 1) / 3);
  return
sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
?>
up
9
CertaiN
7 months ago
The simplest and most efficient implemention for getting remote filesize:

<?php
function remote_filesize($url) {
    static
$regex = '/^Content-Length: *+\K\d++$/im';
    if (!
$fp = @fopen($url, 'rb')) {
        return
false;
    }
    if (
        isset(
$http_response_header) &&
       
preg_match($regex, implode("\n", $http_response_header), $matches)
    ) {
        return (int)
$matches[0];
    }
    return
strlen(stream_get_contents($fp));
}
?>
up
10
Anonymous
3 years ago
if you recently appended something to file, and closed it then this method will not show appended data:
<?php
// get contents of a file into a string
$filename = "/usr/local/something.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
?>
You should insert a call to clearstatcache() before calling filesize()
I've spent two hours to find that =/
up
4
linda dot collins at mailinator dot com
1 year ago
A fast implementation that determines actual file size of large files (>2GB) on 32-bit PHP:

function RealFileSize($fp)
{
    $pos = 0;
    $size = 1073741824;
    fseek($fp, 0, SEEK_SET);
    while ($size > 1)
    {
        fseek($fp, $size, SEEK_CUR);

        if (fgetc($fp) === false)
        {
            fseek($fp, -$size, SEEK_CUR);
            $size = (int)($size / 2);
        }
        else
        {
            fseek($fp, -1, SEEK_CUR);
            $pos += $size;
        }
    }

    while (fgetc($fp) !== false)  $pos++;

    return $pos;
}

Input is an open file handle.  Return value is an integer for file sizes < 4GB, floating-point otherwise.

This starts out by skipping ~1GB at a time, reads a character in, repeats.  When it gets into the last GB, it halves the size whenever the read fails.  The last couple of bytes are just read in.

Some people might have concerns over this function because $pos will become a floating point number after exceeding integer limits and they know of floating point's tendencies to be inaccurate.  On most computers that correctly implement the IEEE floating point spec, $pos will be accurate out to around 9 *petabytes*.  Unless you are working with multi-petabyte files in PHP or the code is executing on strange hardware, this function is going to be more than sufficient.  Every part of this function has been carefully crafted to deal with 32-bit deficiencies.
up
3
frank (at) haua dot net
3 years ago
I have a cli script running that use the filesize function on a ssh2_sftp connection. It has the >2Gb limit issue, while it does not have that issue locally. I have managed to get around this by doing a "du -sb" command through ssh2_shell.

The following function takes the ssh2_connect resource and the path as input. It may not be neat, but it solves the problem for the moment.

<?php
function fSSHFileSize($oConn, $sPath) {
    if(
false !== ($oShell = @ssh2_shell($oConn, 'xterm', null, 500, 24, SSH2_TERM_UNIT_CHARS))) {
       
fwrite($oShell, "du -sb '".$sPath."'".PHP_EOL);
       
sleep(1);
        while(
$sLine = fgets($oShell)) {
           
flush();
           
$aResult[] = $sLine;
        }
       
fclose($oShell);
       
$iSize = 0;
        if(
count($aResult) > 1) {
           
$sTemp = $aResult[count($aResult)-2];
           
$sSize = substr($sTemp, 0, strpos($sTemp, chr(9)));
            if(
is_numeric(trim($sSize))) {
               
$iTemp = (int)$sSize;
                if(
$iTemp > "2000000000") $iSize = $iTemp;
            }
        }
        return
$iSize;
    }
    return
0;
}
?>
up
3
jason dot whitehead dot tas at gmail dot com
6 years ago
I have created a handy function, using parts of code from kaspernj at gmail dot com and md2perpe at gmail dot com, which should get file sizes > 4GB on Windows, Linux and Mac  (at least).

<?php
   
function getSize($file) {
       
$size = filesize($file);
        if (
$size < 0)
            if (!(
strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'))
               
$size = trim(`stat -c%s $file`);
            else{
               
$fsobj = new COM("Scripting.FileSystemObject");
               
$f = $fsobj->GetFile($file);
               
$size = $file->Size;
            }
        return
$size;
    }
?>
up
5
Arseny Mogilev
1 year ago
<?php
/**
* Converts bytes into human readable file size.
*
* @param string $bytes
* @return string human readable file size (2,87 Мб)
* @author Mogilev Arseny
*/
function FileSizeConvert($bytes)
{
   
$bytes = floatval($bytes);
       
$arBytes = array(
           
0 => array(
               
"UNIT" => "TB",
               
"VALUE" => pow(1024, 4)
            ),
           
1 => array(
               
"UNIT" => "GB",
               
"VALUE" => pow(1024, 3)
            ),
           
2 => array(
               
"UNIT" => "MB",
               
"VALUE" => pow(1024, 2)
            ),
           
3 => array(
               
"UNIT" => "KB",
               
"VALUE" => 1024
           
),
           
4 => array(
               
"UNIT" => "B",
               
"VALUE" => 1
           
),
        );

    foreach(
$arBytes as $arItem)
    {
        if(
$bytes >= $arItem["VALUE"])
        {
           
$result = $bytes / $arItem["VALUE"];
           
$result = str_replace(".", "," , strval(round($result, 2)))." ".$arItem["UNIT"];
            break;
        }
    }
    return
$result;
}

?>
up
2
tmont
5 years ago
Here's the best way (that I've found) to get the size of a remote file. Note that HEAD requests don't get the actual body of the request, they just retrieve the headers. So making a HEAD request to a resource that is 100MB will take the same amount of time as a HEAD request to a resource that is 1KB.

<?php
$remoteFile
= 'http://us.php.net/get/php-5.2.10.tar.bz2/from/this/mirror';
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch);
curl_close($ch);
if (
$data === false) {
  echo
'cURL failed';
  exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (
preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
 
$status = (int)$matches[1];
}
if (
preg_match('/Content-Length: (\d+)/', $data, $matches)) {
 
$contentLength = (int)$matches[1];
}

echo
'HTTP Status: ' . $status . "\n";
echo
'Content-Length: ' . $contentLength;
?>

Result:

HTTP Status: 302
Content-Length: 8808759
up
2
Anonymous
1 year ago
This functions returns the exact file size for file larger than 2 GB on 32 bit OS:

<?php
function file_get_size($file) {
   
//open file
   
$fh = fopen($file, "r");
   
//declare some variables
   
$size = "0";
   
$char = "";
   
//set file pointer to 0; I'm a little bit paranoid, you can remove this
   
fseek($fh, 0, SEEK_SET);
   
//set multiplicator to zero
   
$count = 0;
    while (
true) {
       
//jump 1 MB forward in file
       
fseek($fh, 1048576, SEEK_CUR);
       
//check if we actually left the file
       
if (($char = fgetc($fh)) !== false) {
           
//if not, go on
           
$count ++;
        } else {
           
//else jump back where we were before leaving and exit loop
           
fseek($fh, -1048576, SEEK_CUR);
            break;
        }
    }
   
//we could make $count jumps, so the file is at least $count * 1.000001 MB large
    //1048577 because we jump 1 MB and fgetc goes 1 B forward too
   
$size = bcmul("1048577", $count);
   
//now count the last few bytes; they're always less than 1048576 so it's quite fast
   
$fine = 0;
    while(
false !== ($char = fgetc($fh))) {
       
$fine ++;
    }
   
//and add them
   
$size = bcadd($size, $fine);
   
fclose($fh);
    return
$size;
}
?>
up
2
webmaster at eclipse org
7 years ago
On 64-bit platforms, this seems quite reliable for getting the filesize of files > 4GB

<?php
$a
= fopen($filename, 'r');
fseek($a, 0, SEEK_END);
$filesize = ftell($a);
fclose($a);
?>
up
1
k dot reznichak at pcpin dot com
2 months ago
Here ist the very fast and reliable way to get size of large files > 2Gb on 32bit and 64bit platforms.

<?php
 
/**
   * Get the size of file, platform- and architecture-independant.
   * This function supports 32bit and 64bit architectures and works fith large files > 2 GB
   * The return value type depends on platform/architecture: (float) when PHP_INT_SIZE < 8 or (int) otherwise
   * @param   resource $fp
   * @return  mixed (int|float) File size on success or (bool) FALSE on error
   */
 
function my_filesize($fp) {
   
$return = false;
    if (
is_resource($fp)) {
      if (
PHP_INT_SIZE < 8) {
       
// 32bit
       
if (0 === fseek($fp, 0, SEEK_END)) {
         
$return = 0.0;
         
$step = 0x7FFFFFFF;
          while (
$step > 0) {
            if (
0 === fseek($fp, - $step, SEEK_CUR)) {
             
$return += floatval($step);
            } else {
             
$step >>= 1;
            }
          }
        }
      } elseif (
0 === fseek($fp, 0, SEEK_END)) {
       
// 64bit
       
$return = ftell($fp);
      }
    }
    return
$return;
  }
?>
up
0
Anonymous
1 month ago
Here a function to get the size of a file in a human understanding way with decimal separator, thousand separator, decimals...

function convertFileSize($file, $size=null, $decimals=2, $dec_sep='.', $thousands_sep=','){
if (!is_file($file)){
  return "El fichero no existe";
}
$bytes = filesize($file);
$sizes = 'BKMGTP';
if (isset($size)){
  $factor = strpos($sizes, $size[0]);
  if ($factor===false){
   return "El tamaño debe ser B, K, M, G, T o P";
  }
} else {
  $factor = floor((strlen($bytes) - 1) / 3);
  $size = $sizes[$factor];
}
return number_format($bytes / pow(1024, $factor), $decimals, $dec_sep, $thousands_sep).' '.$size;
}

Source: http://softontherocks.blogspot.com/2014/11/obtener-el-tamano-de-un-fichero-y.html
up
0
Svetoslav Marinov
5 years ago
This is an updated version of my previous filesize2bytes.
The return type now it's really an int.

<?php
/**
* Converts human readable file size (e.g. 10 MB, 200.20 GB) into bytes.
*
* @param string $str
* @return int the result is in bytes
* @author Svetoslav Marinov
* @author http://slavi.biz
*/
function filesize2bytes($str) {
   
$bytes = 0;

   
$bytes_array = array(
       
'B' => 1,
       
'KB' => 1024,
       
'MB' => 1024 * 1024,
       
'GB' => 1024 * 1024 * 1024,
       
'TB' => 1024 * 1024 * 1024 * 1024,
       
'PB' => 1024 * 1024 * 1024 * 1024 * 1024,
    );

   
$bytes = floatval($str);

    if (
preg_match('#([KMGTP]?B)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
       
$bytes *= $bytes_array[$matches[1]];
    }

   
$bytes = intval(round($bytes, 2));

    return
$bytes;
}
?>
up
0
Supermagnus
6 years ago
<?php
function getSizeFile($url) {
    if (
substr($url,0,4)=='http') {
       
$x = array_change_key_case(get_headers($url, 1),CASE_LOWER);
        if (
strcasecmp($x[0], 'HTTP/1.1 200 OK') != 0 ) { $x = $x['content-length'][1]; }
        else {
$x = $x['content-length']; }
    }
    else {
$x = @filesize($url); }

    return
$x;
}
?>

In case of you have a redirection in the server (like Redirect Permanent in the .htaccess)

In this case we have for exemple:
    [content-length] => Array

        (

            [0] => 294          // Size requested file

            [1] => 357556     // Real Size redirected file

        )
up
0
core58 at mail dot ru
8 years ago
some notes and modifications to previous post.
refering to RFC, when using HTTP/1.1 your request (either GET or POST or HEAD) must contain Host header string, opposite to HTTP/1.1 where Host ain't required. but there's no sure how your remote server would treat the request so you can add Host anyway (it won't be an error for HTTP/1.0).
host value _must_ be a host name (not CNAME and not IP address).

this function catches response, containing Location header and recursively sends HEAD request to host where we are moved until final response is met.
(you can experience such redirections often when downloading something from php scripts or some hash links that use apache mod_rewrite. most all of dowloading masters handle 302 redirects correctly, so this code does it too (running recursively thru 302 redirections).)

[$counter302] specify how much times your allow this function to jump if redirections are met. If initial limit (5 is default) expired -- it returns 0 (should be modified for your purposes whatever).0
ReadHeader() function is listed in previous post
(param description is placed there too).

<?php
function remote_filesize_thru( $ipAddress, $url, $counter302 = 5 )
{
   
$socket = fsockopen( "10.233.225.2", 8080 );
    if( !
$socket )
    {
       
// failed to open TCP socket connection
        // do something sensible here besides exit();
       
echo "<br>failed to open socket for [$ipAddress]";
        exit();
    }
                   
   
// just send HEAD request to server
   
$head = "HEAD $url HTTP/1.0\r\nConnection: Close\r\n\r\n";
   
// you may use HTTP/1.1 instead, then your request head string _must_ contain "Host: " header
   
fwrite( $socket, $head );
       
   
// read the response header
   
$header = ReadHeader( $socket );
    if( !
$header )
    {
       
// handle empty response here the way you need...
       
Header( "HTTP/1.1 404 Not Found" );
        exit();
    }
   
   
fclose( $socket );
   
   
// check for "Location" header
   
$locationMarker = "Location: ";
   
$pos = strpos( $header, $locationMarker );
    if(
$pos > 0 )
    {
           
$counter302--;
            if(
$counter302 < 0 )
            {
                    
// redirect limit (5 by default) expired -- return some warning or do something sensible here
                   
echo "warning: too long redirection sequence";
                    return
0;
            }

           
// Location is present -- we should determine target host and move there, like any downloading masters do...
            // no need to use regex here
           
$end = strpos( $header, "\n", $pos );
           
$location = trim( substr( $header, $pos + strlen( $locationMarker ), $end - $pos - strlen( $locationMarker ) ), "\\r\\n" );
            
            
// extract pure host (without "http://")
            
$host = explode( "/", $location );
            
$ipa = gethostbyname( $host[2] );
            
// move to Location
            
return remote_filesize_thru( $ipa, $location, $counter302 );
    }
       
   
// try to acquire Content-Length within the response
   
$regex = '/Content-Length:\s([0-9].+?)\s/';
   
$count = preg_match($regex, $header, $matches);
                       
   
// if there was a Content-Length field, its value
    // will now be in $matches[1]
   
if( isset( $matches[1] ) )
         
$size = $matches[1];
    else
         
$size = 0;
   
    return
$size;
}
?>
up
0
aidan at php dot net
9 years ago
This function quickly calculates the size of a directory:
http://aidanlister.com/repos/v/function.dirsize.php

You can convert filesizes to a human readable size using:
http://aidanlister.com/repos/v/function.size_readable.php

For a faster (unix only) implementation, see function.disk-total-space, note #34100
http://www.php.net/manual/en/function.disk-total-space.php#34100

Also of interest is this wikipedia article, discussing the difference between a kilobyte (1000) and a kibibyte (1024).
http://en.wikipedia.org/wiki/Bytes
up
-1
itsrool at gmail dot com
5 years ago
My solution for calculating the directory size:

<?php
/**
* Get the directory size
* @param directory $directory
* @return integer
*/
function dirSize($directory) {
   
$size = 0;
    foreach(new
RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file){
       
$size+=$file->getSize();
    }
    return
$size;
}
?>
up
-4
lito at eordes dot com
1 year ago
A simple and improved function to get the folder size including subfolders:

<?php
function folderSize ($dir)
{
   
$size = 0;
   
$contents = glob(rtrim($dir, '/').'/*', GLOB_NOSORT);

    foreach (
$contents as $contents_value) {
        if (
is_file($contents_value)) {
           
$size += filesize($contents_value);
        } else {
           
$size += realFolderSize($contents_value);
        }
    }

    return
$size;
}

echo
folderSize('/var/www/html/').' bytes';
?>
up
-5
cfv1000 at gmail dot com
1 year ago
To get the filesize of a directory use the built-in function disk_total_space
To Top