I need to get the file size of a file over 2 GB in size. (testing on 4.6 GB file). Is there any way to do this without an external program?
Current status:
filesize()
,stat()
andfseek()
failsfread()
andfeof()
works
There is a possibility to get the file size by reading the file content (extremely slow!).
$size = (float) 0;
$chunksize = 1024 * 1024;
while (!feof($fp)) {
fread($fp, $chunksize);
$size += (float) $chunksize;
}
return $size;
I know how to get it on 64-bit platforms (using fseek($fp, 0, SEEK_END)
and ftell()
), but I need solution for 32-bit platform.
Solution: I've started open-source project for this.
Big File Tools
Big File Tools is a collection of hacks that are needed to manipulate files over 2 GB in PHP (even on 32-bit systems).
I found a nice slim solution for Linux/Unix only to get the filesize of large files with 32-bit php.
You should handle the
$filesize
as string. Trying to casting as int results in a filesize = PHP_INT_MAX if the filesize is larger than PHP_INT_MAX.But although handled as string the following human readable algo works:
so my output for a file larger than 4 Gb is:
You can't reliably get the size of a file on a 32 bit system by checking if filesize() returns negative, as some answers suggest. This is because if a file is between 4 and 6 gigs on a 32 bit system filesize will report a positive number, then negative from 6 to 8 then positive from 8 to 10 and so on. It loops, in a manner of speaking.
So you're stuck using an external command that works reliably on your 32 bit system.
However, one very useful tool is the ability to check if the file size is bigger than a certain size and you can do this reliably on even very big files.
The following seeks to 50 megs and tries to read one byte. It is very fast on my low spec test machine and works reliably even when the size is much greater than 2 gigs.
You can use this to check if a file is greater than 2147483647 bytes (2147483648 is max int on 32 bit systems) and then handle the file differently or have your app issue a warning.
When IEEE double is used (very most of systems), file sizes below ~4EB (etabytes = 10^18 bytes) do fit into double as precise numbers (and there should be no loss of precision when using standard arithmetic operations).
I iterated on the BigFileTools class/answer:
-option to disable curl method because some platforms (Synology NAS for example) don't support FTP protocol for Curl
-extra non posix, but more accurate, implementation of sizeExec, instead of size on disk the actual filesize is returned by using stat instead of du
-correct size results for big files (>4GB) and almost as fast for sizeNativeSeek
-debug messages option
Here's one possible method:
It first attempts to use a platform-appropriate shell command (Windows shell substitution modifiers or *nix/Mac
stat
command). If that fails, it tries COM (if on Windows), and finally falls back tofilesize()
.I wrote an function which returns the file size exactly and is quite fast: