简体   繁体   English

计算目录的子目录大小(PHP)

[英]Calculate subdirectory size of a directory (PHP)

I have a folder that contains subfolders of years (eg 2011, 2012 etc.). 我有一个文件夹,其中包含年份的子文件夹(例如2011、2012等)。 Each year's folder contains month folders (eg 02, 09 etc). 每年的文件夹包含月份文件夹(例如02、09等)。

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 06/2008-52KB

10/2010 - 151MB 10/2010-151MB

27/2012 - 852MB 27/2012-852MB

12/01/2013 - 5GB 2013年12月1日-5GB

Cheers. 干杯。

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 您也可以使用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];
    }
}

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM