(PHP 4, PHP 5)
filesize — 取得文件大小
$filename
)取得指定文件的大小。
filename
文件的路径。
返回文件大小的字节数,如果出错返回 FALSE
并生成一条
E_WARNING
级的错误。
Note: 因为 PHP 的整数类型是有符号整型而且很多平台使用 32 位整型,对 2GB 以上的文件,一些文件系统函数可能返回无法预期的结果 。
Example #1 filesize() 例子
<?php
// 输出类似:somefile.txt: 1024 bytes
$filename = 'somefile.txt';
echo $filename . ': ' . filesize($filename) . ' bytes';
?>
失败时抛出E_WARNING
警告。
Note: 此函数的结果会被缓存。参见 clearstatcache() 以获得更多细节。
自 PHP 5.0.0 起, 此函数也用于某些 URL 包装器。请参见 支持的协议和封装协议以获得支持 stat() 系列函数功能的包装器列表。
lito at eordes dot com (2013-03-06 15:10:12)
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';
?>
rommel at rommelsantor dot com (2011-11-19 00:11:25)
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];
}
?>
Anonymous (2011-01-21 18:58:28)
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 =/
frank (at) haua dot net (2011-01-15 18:19:41)
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;
}
?>
jasondblount (at gmail) (2010-10-15 08:41:06)
Find filesize of any file ( >2GB works fine )
<?php
function ffilesize($file){
$ch = curl_init($file);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
curl_close($ch);
if ($data === false)
return false;
if (preg_match('/Content-Length: (\d+)/', $data, $matches))
return (float)$matches[1];
}
?>
itsrool at gmail dot com (2009-11-12 00:36:15)
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;
}
?>
tmont (2009-07-25 02:05:22)
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
Svetoslav Marinov (2009-07-23 10:24:55)
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;
}
?>
Supermagnus (2008-06-30 03:38:11)
<?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
)
jason dot whitehead dot tas at gmail dot com (2008-02-08 03:14:37)
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;
}
?>
webmaster at eclipse org (2007-11-07 07:30:27)
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);
?>
core58 at mail dot ru (2006-04-14 08:21:56)
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;
}
?>
aidan at php dot net (2005-07-12 21:01:14)
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