Search code examples
phpfile-iox86large-filesfilesize

PHP x86 How to get filesize of > 2 GB file without external program?


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() and fseek() fails
  • fread() and feof() 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).


Solution

  • 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.

    composer install jkuchar/BigFileTools
    

    and use it:

    <?php
    $file = BigFileTools\BigFileTools::createDefault()->getFile(__FILE__);
    echo $file->getSize() . " bytes\n";
    

    Result is BigInteger so you can compute with results

    $sizeInBytes = $file->getSize();
    $sizeInMegabytes = $sizeInBytes->toBigDecimal()->dividedBy(1024*1024, 2, \Brick\Math\RoundingMode::HALF_DOWN);    
    echo "Size is $sizeInMegabytes megabytes\n";
    

    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)

    | Driver           | Time (s) ↓          | Runtime requirements | Platform 
    | ---------------  | ------------------- | --------------       | ---------
    | CurlDriver       | 0.00045299530029297 | CURL extension       | -
    | NativeSeekDriver | 0.00052094459533691 | -                    | -
    | ComDriver        | 0.0031449794769287  | COM+.NET extension   | Windows only
    | ExecDriver       | 0.042937040328979   | exec() enabled       | Windows, Linux, OS X
    | NativeRead       | 2.7670161724091     | -                    | -
    

    You can use BigFileTools with any of these or fastest available is chosen by default (BigFileTools::createDefault())

     use BigFileTools\BigFileTools;
     use BigFileTools\Driver;
     $bigFileTools = new BigFileTools(new Driver\CurlDriver());