0

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.

dda
  • 6,030
  • 2
  • 25
  • 34
user826855
  • 578
  • 1
  • 7
  • 18

2 Answers2

3

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];
    }
}
Baba
  • 94,024
  • 28
  • 166
  • 217
0

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>
Community
  • 1
  • 1
hohner
  • 11,498
  • 8
  • 49
  • 84