Reputation: 598
I have a folder that contains subfolders of years (e.g. 2011, 2012 etc.). Each year's folder contains month folders (e.g 02, 09 etc).
How do I calculate the total size of the month folders and list them along with the year and month folder names?
Example:
Directory Name - Size
06/2008 - 52KB
10/2010 - 151MB
27/2012 - 852MB
12/01/2013 - 5GB
Cheers.
Upvotes: 0
Views: 2373
Reputation: 95131
You can try
echo "<pre>";
$depth = 1;
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
$r = array();
foreach ( $ritit as $splFileInfo ) {
if ($ritit->getDepth() === $depth && $splFileInfo->isDir()) {
printf("%s - %s \n", $splFileInfo, getSize($splFileInfo));
}
}
function getSize($dir, $precision = 2) {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS));
$bytes = 0;
foreach ( $ritit as $v ) {
$bytes += $v->getSize();
}
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
You can also try this approach using FilterIterator
$depth = 1;
$it = new RecursiveDirectoryIterator("./", RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
$it = new FileDepthFilterIterator($it, $depth, FileDepthFilterIterator::ONLY_DIR);
foreach ( $it as $splFileInfo ) {
printf("%s\n", new RecusiveSizeInfo($splFileInfo));
}
Classes used
class FileDepthFilterIterator extends FilterIterator {
private $it;
private $depth;
private $type;
const ONLY_DIR = 1;
const ONLY_FILE = 2;
const BOTH_DIR_FILE = 3;
function __construct(RecursiveIteratorIterator &$iterator, $depth, $type) {
$this->it = &$iterator;
$this->depth = $depth;
$this->type = $type;
parent::__construct($this->it);
}
function accept() {
if ($this->getDepth() != $this->depth) {
return false;
}
if ($this->type == self::ONLY_DIR && ! $this->getInnerIterator()->current()->isDir()) {
return false;
}
if ($this->type == self::ONLY_FILE && ! $this->getInnerIterator()->current()->isFile()) {
return false;
}
return true;
}
}
class RecusiveSizeInfo {
/**
*
* @var SplFileInfo
*/
private $info;
private $numFiles = 0;
private $numFolder = 0;
private $bytes = 0;
function __construct(SplFileInfo $info) {
$this->info = $info;
$this->parse();
}
public function getNumFiles() {
return $this->numFiles;
}
public function getNumFolder() {
return $this->numFolder;
}
public function getBytes() {
return $this->bytes;
}
public function __toString() {
return sprintf("%s\t%s\t%s", $this->info, $this->formatSize($this->getBytes()), json_encode(array("file" => $this->numFiles,"dir" => $this->numFolder)));
}
private function parse() {
$ritit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->info , RecursiveDirectoryIterator::SKIP_DOTS),RecursiveIteratorIterator::SELF_FIRST);
foreach ( $ritit as $v ) {
$v->isFile() and $this->numFiles ++;
$v->isDir() and $this->numFolder ++;
$this->bytes += $v->getSize();
}
}
private function formatSize($bytes) {
$units = array('B','KB','MB','GB','TB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, 2) . ' ' . $units[$pow];
}
}
Upvotes: 3
Reputation: 11588
Look at this answer to work out the size of directories. To implement, you're going to need to traverse your directory structure recursively, or manually specify the directories you want:
<li>2012/01 <?php echo foldersize('/2012/01'); ?></li>
<li>2012/02 <?php echo foldersize('/2012/01'); ?></li>
Upvotes: 0