The best way to get the file size which greater than 2GB in php?
Asked Answered
E

7

3

I want to check the file's size of local drives on windows OS.But the native PHP function filesize() only work when the file size less than 2GB. The file which greater than 2GB will return the wrong number.So,is there other way to get the file size which greater than 2GB?

Thank you very much!!

Entomo answered 4/3, 2011 at 0:37 Comment(1)
what operating system are you running php on?Inseverable
A
4

You can always use the system's file size method.

For Windows: Windows command for file size only?

@echo off

echo %~z1

For Linux

stat -c %s filenam

You would run these through the exec php command.

Assyria answered 4/3, 2011 at 0:42 Comment(1)
OS independent implementation can be found here github.com/jkuchar/BigFileToolsMicroanalysis
T
3

PHP function to get the file size of a local file with insignificant memory usage:

function get_file_size ($file) {
   $fp = @fopen($file, "r");
   @fseek($fp,0,SEEK_END);
   $filesize = @ftell($fp);
   fclose($fp);
   return $filesize;
}

In first line of code, $file is opened in read-only mode and attached to the $fp handle.
In second line, the pointer is moved with fseek() to the end of $file.
Lastly, ftell() returns the byte position of the pointer in $file, which is now the end of it.
The fopen() function is binary-safe and it's apropiate for use even with very large files.
The above code is also very fast.

Thinking answered 8/2, 2019 at 12:4 Comment(0)
Y
1

this function works for any size:

function fsize($file) {
  // filesize will only return the lower 32 bits of
  // the file's size! Make it unsigned.
  $fmod = filesize($file);
  if ($fmod < 0) $fmod += 2.0 * (PHP_INT_MAX + 1);

  // find the upper 32 bits
  $i = 0;

  $myfile = fopen($file, "r");

  // feof has undefined behaviour for big files.
  // after we hit the eof with fseek,
  // fread may not be able to detect the eof,
  // but it also can't read bytes, so use it as an
  // indicator.
  while (strlen(fread($myfile, 1)) === 1) {
    fseek($myfile, PHP_INT_MAX, SEEK_CUR);
    $i++;
  }

  fclose($myfile);

  // $i is a multiplier for PHP_INT_MAX byte blocks.
  // return to the last multiple of 4, as filesize has modulo of 4 GB (lower 32 bits)
  if ($i % 2 == 1) $i--;

  // add the lower 32 bit to our PHP_INT_MAX multiplier
  return ((float)($i) * (PHP_INT_MAX + 1)) + $fmod;
}

note: this function maybe litte slow for files > 2gb

(taken from php comments)

Yuhas answered 4/3, 2011 at 0:37 Comment(4)
Looks like you've pulled that from the comments on the PHP filesize manual page.Decant
Downvoted since this answer is an exact copy of other site's content without any attribution or additional insight. It's not even the PHP manual content (which I could understand but would still like to see a link), it's a user-contributed comment. Most things are derivative, but always attribute!Anthracnose
ops sorry yes of course it is form that comment. Didn't want to take the "copyright", I thought it was oblivious it was taken from there :)Frecklefaced
On a Linux 32bits machine, this function returns the actual size plus the php max int, which is wrong. If I removed the if ($fmod < 0) $fmod += 2.0 * (PHP_INT_MAX + 1); line, it gave me the correct size. Did anybody tried it?Caryncaryo
S
0

If you're running a Linux server, use the system command.

$last_line = system('ls');

Is an example of how it is used. If you replace 'ls' with:

du <filename>

then it will return an integer of the file size in the variable $last_line. For example:

472    myProgram.exe

means it's 472 KB. You can use regular expressions to obtain just the number. I haven't used the du command that much, so you'd want to play around with it and have a look at what the output is for files > 2gb.

http://php.net/manual/en/function.system.php

Septilateral answered 4/3, 2011 at 0:47 Comment(1)
I think you could pipe this to awk... so ls -nl filename | awk '{print $1}' to get just the number; awk is really cool.Mozzetta
M
0
<?php
$files = `find / -type f -size +2097152`;
?>
Monologue answered 4/3, 2011 at 0:52 Comment(2)
I think he wanted the size of a known file. But good method to find files large then 2GB :)Assyria
"I want to check the file's size of local drives on windows OS"Mahican
L
0

This function returns the size for files > 2GB and is quite fast.

function file_get_size($file) {
    //open file
    $fh = fopen($file, "r"); 
    //declare some variables
    $size = "0";
    $char = "";
    //set file pointer to 0; I'm a little bit paranoid, you can remove this
    fseek($fh, 0, SEEK_SET);
    //set multiplicator to zero
    $count = 0;
    while (true) {
        //jump 1 MB forward in file
        fseek($fh, 1048576, SEEK_CUR);
        //check if we actually left the file
        if (($char = fgetc($fh)) !== false) {
            //if not, go on
            $count ++;
        } else {
            //else jump back where we were before leaving and exit loop
            fseek($fh, -1048576, SEEK_CUR);
            break;
        }
    }
    //we could make $count jumps, so the file is at least $count * 1.000001 MB large
    //1048577 because we jump 1 MB and fgetc goes 1 B forward too
    $size = bcmul("1048577", $count);
    //now count the last few bytes; they're always less than 1048576 so it's quite fast
    $fine = 0;
    while(false !== ($char = fgetc($fh))) {
        $fine ++;
    }
    //and add them
    $size = bcadd($size, $fine);
    fclose($fh);
    return $size;
}
Lariat answered 24/7, 2013 at 23:2 Comment(0)
H
0

To riff on joshhendo's answer, if you're on a Unix-like OS (Linux, OSX, macOS, etc) you can cheat a little using ls:

$fileSize = trim(shell_exec("ls -nl " . escapeshellarg($fullPathToFile) . " | awk '{print $5}'"));

trim() is there to remove the carriage return at the end. What's left is a string containing the full size of the file on disk, regardless of size or stat cache status, with no human formatting such as commas.

Just be careful where the data in $fullPathToFile comes from...when making system calls you don't want to trust user-supplied data. The escapeshellarg will probably protect you, but better safe than sorry.

Heppman answered 6/2, 2017 at 23:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.