0

我有一个文件夹,其中包含年份的子文件夹(例如 2011、2012 等)。每年的文件夹包含月份文件夹(例如 02、09 等)。

如何计算月份文件夹的总大小并将它们与年份和月份文件夹名称一起列出?

例子:

目录名称 - 大小

06/2008 - 52KB

10/2010 - 151MB

27/2012 - 852MB

2013 年 12 月 1 日 - 5GB

干杯。

4

2 回答 2

3

你可以试试

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

您也可以尝试使用这种方法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));
}

使用的类

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];
    }
}
于 2013-01-19T17:43:54.233 回答
0

查看此答案以计算目录的大小。要实现,您将需要递归遍历目录结构,或手动指定所需的目录:

<li>2012/01 <?php echo foldersize('/2012/01'); ?></li>
<li>2012/02 <?php echo foldersize('/2012/01'); ?></li>
于 2013-01-19T14:36:57.130 回答