我有一个目录,其中包含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;
}
答案 0 :(得分:1)
您应该查看SPL中提供的recursiveDirectoryIterator
和recursiveIteratorIterator
类。这应该很好地满足您的需求。
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迭代器没有很好地记录,所以我将尝试解释:
foreach
循环RecursiveDirectoryIterator
是文件系统的递归迭代器。递归迭代器是一种特殊类型的迭代器,它在每次迭代中自己产生一个迭代器。它们可用于嵌套数据结构。SKIP_DOTS
告诉它忽略.
和..
条目RecursiveIteratorIterator
用于“展平”递归迭代器。它会传递一个递归迭代器,并在一个循环中产生所有后续条目。SELF_FIRST
表示父母在子女面前(即2009年至2009年之前的2009年)屈服。$subdirPath
是每个项的路径,值$subdirInfo
是一个SplFileInfo
对象(实际上,它是RecursiveDirectoryIterator本身,它从SplFileInfo中扩展而来结束 - 但此时无所谓)下一步是重构你的foldersize()
函数以使用迭代器。对所有文件和大小计算的迭代一次是明智的。 编辑:看看Mike Brant对这种解决方案的回答,上面的解释也适用于此。