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).
If you have an FTP server you could use fsockopen:
(Found as a comment on the ftp_size page)
I've started project called Big File Tools. It is proven to work on Linux, Mac and Windows (even 32-bit variants). It provides byte-precise results even for huge files (>4GB). Internally it uses brick/math - arbitrary-precision arithmetic library.
Install it using composer.
and use it:
Result is BigInteger so you can compute with results
Big File Tools internally uses drivers to reliably determine exact file size on all platforms. Here is list of available drivers (updated 2016-02-05)
You can use BigFileTools with any of these or fastest available is chosen by default (
BigFileTools::createDefault()
)Use as follow:
And where you want:
If you want improve it you are welcome!
This works for me on a Windows Box.
I was looking through the bug log here: https://bugs.php.net/bug.php?id=63618 and found this solution.
Well easyest way to do that would be to simply add a max value to your number. This means on x86 platform long number add 2^32:
example: Big_File.exe - 3,30Gb (3.554.287.616 b) your function returns -740679680 so you add 2^32 (4294967296) and get 3554287616.
You get negative number because your system reserves one bit of memory to the negative sign, so you are left with 2^31 (2.147.483.648 = 2G) maximum value of either negative or positive number. When system reaches this maximum value it doesn't stop but simply overwrites that last reserved bit and your number is now forced to negative. In simpler words, when you exceed maximum positive number you will be forced to maximum negative number, so 2147483648 + 1 = -2147483648. Further addition goes towards zero and again towards maximum number.
As you can see it is like a circle with highest and lowest numbers closing the loop.
Total maximum number that x86 architecture can "digest" in one tick is 2^32 = 4294967296 = 4G, so as long as your number is lower than that, this simple trick will always work. In higher numbers you must know how many times you have passed the looping point and simply multiply it by 2^32 and add it to your result:
Ofcourse in basic PHP functions this is quite hard to do, because no function will tell you how many times it has passed the looping point, so this won't work for files over 4Gigs.
you may want to add some alternatives to the function you use such as calling system functions such as "dir" / "ls" and get the information from there. They are subject of security of course, things you can check and eventually revert to the slow method as a last resort only.