在php中获取大于2GB的文件大小的最佳方法是什么?

时间:2011-03-04 00:37:00

标签: php filesize

我想检查文件在windows OS上的本地驱动器的大小。但是本机PHP函数filesize()仅在文件大小小于2GB时才有效。大于2GB的文件将返回错误的数字。那么,还有其他方法可以获得大于2GB?的文件大小

非常感谢!!

7 个答案:

答案 0 :(得分:4)

您始终可以使用系统的文件大小方法。

对于Windows: Windows command for file size only?

  

@echo off

     

echo%〜z1

对于Linux

stat -c %s filenam

您可以通过exec php命令运行这些命令。

答案 1 :(得分:1)

此功能适用于任何尺寸:

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;
}

注意:对于文件而言,此功能可能很慢。 2GB

(摘自php评论)

答案 2 :(得分:1)

PHP函数获取内存使用量不大的本地文件的文件大小:

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

在第一行代码中,$file以只读模式打开,并附加到$fp句柄。
在第二行中,指针用fseek()移动到$file的末尾。
最后,ftell()返回指针在$file中的字节位置,该位置现已结束。
fopen()函数是二进制安全的,即使在非常大的文件中也很适合使用。
上面的代码也非常快。

答案 3 :(得分:0)

如果您正在运行Linux服务器,请使用系统命令。

$last_line = system('ls');

是一个如何使用它的例子。如果将'ls'替换为:

du <filename>

然后它将在变量$ last_line中返回文件大小的整数。例如:

472    myProgram.exe

意味着它是472 KB。您可以使用正则表达式来获取该数字。我没有那么多地使用du命令,所以你想要玩它并查看文件的输出&gt; 2GB。

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

答案 4 :(得分:0)

<?php
$files = `find / -type f -size +2097152`;
?>

答案 5 :(得分:0)

此函数返回文件的大小&gt; 2GB并且非常快。

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;
}

答案 6 :(得分:0)

要对joshhendo's answer进行搜索,如果您使用的是类Unix操作系统(Linux,OSX,macOS等),您可以使用ls作弊:

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

trim()可以在最后删除回车符。剩下的是一个字符串,其中包含磁盘上文件的完整大小,无论大小或统计缓存状态如何,没有人为格式,如逗号。

请注意$fullPathToFile中的数据来自......在进行系统调用时,您不想信任用户提供的数据。 escapeshellarg 可能会保护您,但比抱歉更安全。