1

年 (例: 2009) のサブディレクトリを含むディレクトリがあり、これらのサブディレクトリ内には月 (例: 02) のサブディレクトリが含まれています。

各月のフォルダー内の合計ファイルと、各フォルダーの合計ファイル サイズを計算し、年と月のフォルダー名と共に 2 つの合計 (合計サイズと合計ファイル) を出力する必要があります。

例:

  • 2009 年 5 月 - 512MB (12 ファイル)

  • 2009 年 6 月 - 45KB (21 ファイル)

  • 2009 年 7 月 - 6MB (8 ファイル)

  • 2011 年 1 月 - 54MB (2 ファイル)

  • 2011 年 4 月 - 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;
}
4

2 に答える 2

1

recursiveDirectoryIteratorSPL で提供されているおよび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";
于 2013-01-21T23:15:48.763 に答える
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.and..エントリを無視するように指示します
  • RecursiveIteratorIterator、再帰イテレータを「平坦化」するために使用されます。再帰イテレータが渡され、単一のループで後続のすべてのエントリが生成されます。
  • SELF_FIRST親が子より先に譲られることを意味します (つまり、2009/01 より前の 2009)。
  • ループでは、キー$subdirPathは各アイテムのパスであり、値$subdirInfoSplFileInfoオブジェクトです (実際、最後に SplFileInfo から拡張されるのは RecursiveDirectoryIterator 自体ですが、この時点では問題ありません)。
  • isDir() は、現在のアイテムがディレクトリかどうかをチェックします

foldersize()次のステップは、イテレータも使用するように関数をリファクタリングすることです。すべてのファイルの反復とサイズ計算を一度に行うのは賢明かもしれません。編集:そのような解決策については、Mike Brant からの回答を見てください。上記の説明はそれにも当てはまります。

于 2013-01-21T23:34:25.987 に答える