2013-01-21 30 views
1

我有一個包含年份的子目錄的目錄(如2009年),並在這些子目錄包含幾個月的子目錄(如02)返回月份和年份目錄名和文件夾大小

我需要計算總每個月份文件夾中的文件以及每個文件夾的總文件大小,並將兩個總計(總大小爲&的文件總數)與年份和月份文件夾名稱一起輸出。

實施例:

  • 05/2009 - 512MB(12個文件)

  • 06/2009 - 45KB(21個文件)

  • 07/2009 - 6MB(8文件)

  • 01/2011 - 54MB(2個文件)

  • 04/2011 - 652MB(55個文件)

...

我已經創建了下面的函數,將計算目錄的總大小和文件。如何調整它以滿足上面列出的多個子文件夾列表?

function foldersize($path) { 
    $total_size = 0; 
    $total_files = 0; 

    $files = scandir($path); 

    foreach($files as $file) { 
     if ($t<>"." && $t <> "..") { 
      if (is_dir($path.'/'.$file)) { 
       $size = foldersize($path.'/'.$file); 
       $total_files++; 
       $total_size += $size; 
      } 
      else { 
       $size = filesize($path.'/'.$file); 
       $total_files++; 
       $total_size += $size; 
      } 
     } 
    } 

    return $total_size.' | '.$total_files; 
} 

回答

1

你應該看看在SPL提供的recursiveDirectoryIteratorrecursiveIteratorIterator類。這應該很好地滿足您的需求。

http://php.net/manual/en/class.recursivedirectoryiterator.php http://php.net/manual/en/class.recursiveiteratoriterator.php

使用範例:

$path = realpath('/path/to/directory'); 
$total_files = 0; 
$total_filesize = 0; 
$dir_files = 0; 
$dir_filesize = 0; 

$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST); 
$first_dir = true; 
foreach($iterator as $path => $object){ 
    if ($path->isDir()) { 
     // echo out information from last directory 
     if (false === $first_dir) { 
      echo "Number of Files in Directory: " . $dir_files . "\nTotal File Size of Directory: " . $dir_filesize . " bytes\n\n"; 
      // reset directory counters 
      $dir_files = 0; 
      $dir_filesize = 0; 
     } 
     // start new directory output 
     echo $path->getPathname() . "\n"; 
    } else if ($path->isFile()) { 
     $total_filesize += $path->getSize(); 
     $dir_filesize += $path->getSize(); 
     $total_files++; 
     $dir_files++; 
    } 
} 

echo "\nTotal Files: " . $total_files . "\nTotal File Size: " . $total_filesize . " bytes"; 
1

您應該使用RecursiveDirectoryIterator遍歷子目錄遞歸。

$_recursiveIterator = new RecursiveDirectoryIterator(
    $path, FilesystemIterator::SKIP_DOTS); 
$iterator = new RecursiveIteratorIterator(
    $_recursiveIterator, RecursiveIteratorIterator::SELF_FIRST); 
foreach($iterator as $subdirPath => $subdirInfo) { 
    if ($subdirInfo->isDir()) { 
     echo $subdirPath . ' ' . foldersize($subdirPath); 
    } 
} 

這裏會發生什麼事是有點難以理解和SPL迭代器不記錄很好,所以我會盡力解釋:

  • Iterators是實現一個特殊的接口的對象,使他們能 用於foreach循環
  • RecursiveDirectoryIterator是文件系統的遞歸迭代器。遞歸迭代器是一種特殊類型的迭代器,它在每次迭代中都會產生一個迭代器。它們可以用於嵌套數據結構。
  • SKIP_DOTS告訴它忽略...
  • RecursiveIteratorIterator是用來「壓平」遞歸迭代器。它通過遞歸迭代器並在單個循環中產生所有後續條目。
  • SELF_FIRST意味着父母在他們的孩子面前屈服(即2009年以前2009/01)在環路
  • ,關鍵是$subdirPath每個項目和值的路徑$subdirInfo一個SplFileInfo對象(事實上,它是從SplFileInfo延伸到底RecursiveDirectoryIterator本身 - 但沒有按」在這點T物質)
  • ISDIR()檢查當前產品目錄

下一步將重構你的foldersize()功能使用迭代器了。一次迭代所有文件和大小計算可能是明智的。 編輯:看看邁克布蘭特爲這樣的解決方案的答案,上面的解釋也適用於此。

+0

+1有關使用迭代器的很好的詳細解釋。 –