问题
I have been struggeling on how to get the valid filesize of a file that is >= 2 GB in PHP.
Example
Here I am checking the filesize of a file that is 3,827,394,560 bytes large with the filesize() function:
echo "The file is " . filesize('C:\MyFile.rar') . " bytes.";
Result
This is what it returns:
The file is -467572736 bytes.
Background
PHP uses signed integers, which means that the maximum number it can represent is 2,147,483,647 (+/- 2 GB).
This is where it is limited.
回答1:
http://us.php.net/manual/en/function.filesize.php#102135 gives a complete and correct means for finding the size of a file larger than 2GB in PHP, without relying on OS-specific interfaces.
The gist of it is that you first use filesize
to get the "low" bits, then open+seek the file to determine how many multiples of 2GB it contains (the "high" bits).
回答2:
The solution I tried and apparently works is to use the "Size" property of the COM FileObject. I am not entirely sure what type it uses.
This is my code:
function real_filesize($file_path)
{
$fs = new COM("Scripting.FileSystemObject");
return $fs->GetFile($file_path)->Size;
}
It's simply called as following:
$file = 'C:\MyFile.rar';
$size = real_filesize($file);
echo "The size of the file is: $size";
Result
The size of the file is: 3,827,394,560 bytes
回答3:
I was using a different approach, saving precious server-resources, have a look at my GitHub repository github.com/eladkarako/download.eladkarako.com.
It is a plain, and complete, download-dashboard, that overcome the (*rare) cases of filesize
error using client-side head-request, granted, it will not be embedded into the page's HTML source, but rendered (*fixed) some time later, so it is more suitable for hmm..., lets say, relaxed scenarios..
To make this solution available, an Apache .htaccess
(or header in PHP) should be added allowing client-side usage of Content-Length
value.
Essentially you can slim down the .htaccess
to just allowing Content-Length
removing other CORS rules.. making the website more secure.
no jQuery was used and whole thing was written in my Samsung text-editor and uploaded by FTP from my smartphone, in a 1.5-hour train-ride in my MILUIM.. and yet, still impeccable ;)
回答4:
I have one "hacky" solution what works well.
Look please THIS function how I do it and you need also include this class to function can works well or change by your need.
example:
include_once 'class.os.php';
include_once 'function.filesize.32bit.php';
// Must be real path to file
$file = "/home/username/some-folder/yourfile.zip";
echo get_filesize($file);
This function is not ideal solution but here is how works:
- First check if
shell_exec
is enabled into PHP. If is enabled, it will check via shell command real filesize. - If shell fail and OS is 64bit will return normal
filesize()
information - If is 32bit will go into "chunking" method and calculate filesize reading buytes.
NOTE!
Alfter reading keep results in string format to can easly calculate because PHP can calculate strings but if you transfrorm results over 2GB into integer you will have same problem as before.
WARNING!
Chunking is realy slow and if you want to loop this, you will have memory leak or script can take minutes to finish reading all the files. If you use this function on server where you have shell_exec
enabled, you will have super fast reading.
P.S.
If you have some idea for changes here and improvemants feel free to commit.
回答5:
I know this is an oldie, but I'm using PHP x64 5.5.38 (for now) and don't want to upgrade to the latest 7.x version yet.
I did read all these posts about finding file sizes that are larger than 2GB, but all solutions where very slow for large amount of files.
So, yesterday I've created C/C++ PHP Extension "php_filesize.dll", that is using the power of C/C++ to find file sizes with a few methods I've found, it's also UTF-8 compatible and very fast.
You can try it: http://www.jobnik.org/files/PHP/php_filesize.zip
Usage:
methods:
0 - using GetFileAttributesEx
1 - using CreateFile
2 - using FindFirstFile
-1 - using stat64 (default and optional)
$fsize = php_filesize("filepath", $method_optional);
- Returns file size in string type up to 9 PetaByte
Credits:
FileSize methods: Check filesize without opening file in c++?
UTF-8 support: https://github.com/kenjiuno/php-wfio
回答6:
For anyone who happens to be on a linux host, the easiest solution I found is to use:
exec("stat --format=\"%s\" \"$file\"");
This assumes no quotation marks or newlines in the file name and technically returns a string instead of a number I suppose, but it works well with this method to get a human readable file size.
The largest file I tested this with was about 3.6 GB.
回答7:
To get the correct file size I often use this piece of code written by myself some months ago. My code uses: exec
/com
/stat
where available. I know its limits, but it's a good starting point. The best idea is using filesize()
on 64bit architecture.
<?php
######################################################################
# Human size for files smaller or bigger than 2 GB on 32 bit Systems #
# size.php - 1.3 - 21.09.2015 - Alessandro Marinuzzi - www.alecos.it #
######################################################################
function showsize($file) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
if (class_exists("COM")) {
$fsobj = new COM('Scripting.FileSystemObject');
$f = $fsobj->GetFile(realpath($file));
$size = $f->Size;
} else {
$size = trim(@exec("for %F in (\"" . $file . "\") do @echo %~zF"));
}
} elseif (PHP_OS == 'Darwin') {
$size = trim(@exec("stat -f %z " . $file));
} else {
$size = trim(@exec("stat -c %s " . $file));
}
if ((!is_numeric($size)) || ($size < 0)) {
$size = filesize($file);
}
if ($size < 1024) {
echo $size . ' Byte';
} elseif ($size < 1048576) {
echo number_format(round($size / 1024, 2), 2) . ' KB';
} elseif ($size < 1073741824) {
echo number_format(round($size / 1048576, 2), 2) . ' MB';
} elseif ($size < 1099511627776) {
echo number_format(round($size / 1073741824, 2), 2) . ' GB';
} elseif ($size < 1125899906842624) {
echo number_format(round($size / 1099511627776, 2), 2) . ' TB';
} elseif ($size < 1152921504606846976) {
echo number_format(round($size / 1125899906842624, 2), 2) . ' PB';
} elseif ($size < 1180591620717411303424) {
echo number_format(round($size / 1152921504606846976, 2), 2) . ' EB';
} elseif ($size < 1208925819614629174706176) {
echo number_format(round($size / 1180591620717411303424, 2), 2) . ' ZB';
} else {
echo number_format(round($size / 1208925819614629174706176, 2), 2) . ' YB';
}
}
?>
<?php include("php/size.php"); ?>
<?php showsize("files/VeryBigFile.tar"); ?>
I hope this helps.
来源:https://stackoverflow.com/questions/9346104/php-filesize-on-files-2-gb