返回月份和年份目录名称和文件夹大小

时间:2013-01-21 22:52:31

标签: php

我有一个目录,其中包含Year的子目录(例如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;
}

2 个答案:

答案 0 :(得分: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 :(得分: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年之前的2009年)屈服。
  • 在循环中,键$subdirPath是每个项的路径,值$subdirInfo是一个SplFileInfo对象(实际上,它是RecursiveDirectoryIterator本身,它从SplFileInfo中扩展而来结束 - 但此时无所谓)
  • isDir()检查当前项目是否为目录

下一步是重构你的foldersize()函数以使用迭代器。对所有文件和大小计算的迭代一次是明智的。 编辑:看看Mike Brant对这种解决方案的回答,上面的解释也适用于此。