Как получить размер каталога в PHP - PullRequest
51 голосов
/ 25 января 2009
function foldersize($path) {
  $total_size = 0;
  $files = scandir($path);

  foreach($files as $t) {
    if (is_dir(rtrim($path, '/') . '/' . $t)) {
      if ($t<>"." && $t<>"..") {
          $size = foldersize(rtrim($path, '/') . '/' . $t);

          $total_size += $size;
      }
    } else {
      $size = filesize(rtrim($path, '/') . '/' . $t);
      $total_size += $size;
    }
  }
  return $total_size;
}

function format_size($size) {
  $mod = 1024;
  $units = explode(' ','B KB MB GB TB PB');
  for ($i = 0; $size > $mod; $i++) {
    $size /= $mod;
  }

  return round($size, 2) . ' ' . $units[$i];
}

$SIZE_LIMIT = 5368709120; // 5 GB

$sql="select * from users order by id";
$result=mysql_query($sql);

while($row=mysql_fetch_array($result)) {
  $disk_used = foldersize("C:/xampp/htdocs/freehosting/".$row['name']);

  $disk_remaining = $SIZE_LIMIT - $disk_used;
  print 'Name: ' . $row['name'] . '<br>';

  print 'diskspace used: ' . format_size($disk_used) . '<br>';
  print 'diskspace left: ' . format_size($disk_remaining) . '<br><hr>';
}

php disk_total_space

Есть идеи, почему загрузка процессора слишком высокая или 100%, пока выполнение скрипта не закончится? Можно ли что-то сделать, чтобы оптимизировать это? или есть другой альтернативный способ проверить папку и папки внутри нее по размеру?

Ответы [ 18 ]

2 голосов
/ 25 января 2009

Есть несколько вещей, которые вы могли бы сделать для оптимизации скрипта, но максимальный успех сделал бы его связанным с IO, а не с процессором:

  1. Рассчитать rtrim($path, '/') вне цикла.
  2. сделать if ($t<>"." && $t<>"..") внешним тестом - ему не нужно указывать путь
  3. Рассчитайте rtrim($path, '/') . '/' . $t один раз за цикл - внутри 2) и с учетом 1).
  4. Рассчитать explode(' ','B KB MB GB TB PB'); один раз, а не каждый вызов?
1 голос
/ 13 июня 2018

Однострочное решение. Результат в байтах.

$size=array_sum(array_map('filesize', glob("{$dir}/*.*")));

Дополнительный бонус: вы можете просто изменить маску файла на любую, какую хотите, и считать только определенные файлы (например, по расширению).

1 голос
/ 26 октября 2018

Работает отлично.

     public static function folderSize($dir)
     {
        $size = 0;

        foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
            $func_name = __FUNCTION__;
            $size += is_file($each) ? filesize($each) : static::$func_name($each);
        }

        return $size;
      }
1 голос
/ 21 января 2017

Просто еще одна функция, использующая собственные функции php.

function dirSize($dir)
    {
        $dirSize = 0;
        if(!is_dir($dir)){return false;};
        $files = scandir($dir);if(!$files){return false;}
        $files = array_diff($files, array('.','..'));

        foreach ($files as $file) {
            if(is_dir("$dir/$file")){
                 $dirSize += dirSize("$dir/$file");
            }else{
                $dirSize += filesize("$dir/$file");
            }
        }
        return $dirSize;
    }

ПРИМЕЧАНИЕ: эта функция возвращает размеры файлов, а НЕ размер на диске

1 голос
/ 26 ноября 2016

Объектно-ориентированный подход:

/**
 * Returns a directory size
 *
 * @param string $directory
 *
 * @return int $size directory size in bytes
 *
 */
function dir_size($directory)
{
    $size = 0;
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file)
    {
        $size += $file->getSize();
    }
    return $size;
}

Быстрый и яростный подход:

function dir_size2($dir)
{
    $line = exec('du -sh ' . $dir);
    $line = trim(str_replace($dir, '', $line));
    return $line;
}
1 голос
/ 17 августа 2016

Что касается примера Джонатана Сэмпсона для Linux, обратите внимание, когда вы делаете intval для результата функции du, если размер> 2 ГБ, он будет продолжать отображать 2 ГБ.

Заменить:

$totalSize = intval(fgets($io, 80));

по:

strtok(fgets($io, 80), " ");

предполагается, что ваша функция "du" возвращает размер, разделенный пробелом, за которым следует имя каталога / файла.

0 голосов
/ 19 июля 2018

Код настроен для доступа к основному каталогу и всем подпапкам внутри него. Это вернет полный размер каталога.

function get_dir_size($directory){
    $size = 0;
    $files= glob($directory.'/*');
    foreach($files as $path){
        is_file($path) && $size += filesize($path);

        if (is_dir($path))
        {
            $size += get_dir_size($path);
        }
    }
    return $size;
}
0 голосов
/ 13 марта 2013

Evolved from Nate Haugs answer Я создал короткую функцию для своего проекта:

function uf_getDirSize($dir, $unit = 'm')
{
    $dir = trim($dir, '/');
    if (!is_dir($dir)) {
        trigger_error("{$dir} not a folder/dir/path.", E_USER_WARNING);
        return false;
    }
    if (!function_exists('exec')) {
        trigger_error('The function exec() is not available.', E_USER_WARNING);
        return false;
    }
    $output = exec('du -sb ' . $dir);
    $filesize = (int) trim(str_replace($dir, '', $output));
    switch ($unit) {
        case 'g': $filesize = number_format($filesize / 1073741824, 3); break;  // giga
        case 'm': $filesize = number_format($filesize / 1048576, 1);    break;  // mega
        case 'k': $filesize = number_format($filesize / 1024, 0);       break;  // kilo
        case 'b': $filesize = number_format($filesize, 0);              break;  // byte
    }
    return ($filesize + 0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...