【问题标题】:PHP count total files in directory AND subdirectory functionPHP计算目录和子目录函数中的文件总数
【发布时间】:2012-06-09 08:30:57
【问题描述】:

我需要获取指定目录中 JPG 文件的总数,包括它的所有子目录。没有子子目录。

结构如下:

目录1/ 2 个文件 子目录 1/ 8 个文件

总共 dir1 = 10 个文件

目录2/ 5 个文件 子目录 1/ 2 个文件 子目录 2/ 8 个文件

总共 dir2 = 15 个文件

我有这个功能,它不能正常工作,因为它只计算最后一个子目录中的文件,总数是实际文件数量的 2 倍。 (如果我在最后一个子目录中有 40 个文件,将输出 80)

public function count_files($path) { 
global $file_count;

$file_count = 0;
$dir = opendir($path);

if (!$dir) return -1;
while ($file = readdir($dir)) :
    if ($file == '.' || $file == '..') continue;
    if (is_dir($path . $file)) :
        $file_count += $this->count_files($path . "/" . $file);
    else :
        $file_count++;
    endif;
endwhile;

closedir($dir);
return $file_count;
}

【问题讨论】:

    标签: php file count directory


    【解决方案1】:

    Developer 的回答真的很棒! 像这样使用它来使其工作:

    System("查找 .-type f -print | wc -l");

    【讨论】:

      【解决方案2】:
      error_reporting(E_ALL);
      
      function printTabs($level)
      {
          echo "<br/><br/>";
          $l = 0;
          for (; $l < $level; $l++)
              echo ".";
      }
      
      function printFileCount($dirName, $init)
      {
          $fileCount = 0;
          $st        = strrpos($dirName, "/");
          printTabs($init);
          echo substr($dirName, $st);
      
          $dHandle   = opendir($dirName);
          while (false !== ($subEntity = readdir($dHandle)))
          {
              if ($subEntity == "." || $subEntity == "..")
                  continue;
              if (is_file($dirName . '/' . $subEntity))
              {
                  $fileCount++;
              }
              else //if(is_dir($dirName.'/'.$subEntity))
              {
                  printFileCount($dirName . '/' . $subEntity, $init + 1);
              }
          }
          printTabs($init);
          echo($fileCount . " files");
      
          return;
      }
      
      printFileCount("/var/www", 0);
      

      刚刚检查,它正在工作。但是结果对齐不好,逻辑有效

      【讨论】:

        【解决方案3】:

        如果有人想计算文件和目录的总数。

        显示/计算总目录和子目录计数

        find . -type d -print | wc -l
        

        显示/计算主目录和子目录中的文件总数

        find . -type f -print | wc -l
        

        仅显示/计算当前目录中的文件(无子目录)

        find . -maxdepth 1 -type f -print | wc -l
        

        显示/计算当前目录(无子目录)中的总目录和文件

        ls -1 | wc -l
        

        【讨论】:

        • 投了反对票,因为这绝不是回答问题
        【解决方案4】:

        为了好玩,我把它放在一起:

        class FileFinder
        {
            private $onFound;
        
            private function __construct($path, $onFound, $maxDepth)
            {
                // onFound gets called at every file found
                $this->onFound = $onFound;
                // start iterating immediately
                $this->iterate($path, $maxDepth);
            }
        
            private function iterate($path, $maxDepth)
            {
                $d = opendir($path);
                while ($e = readdir($d)) {
                    // skip the special folders
                    if ($e == '.' || $e == '..') { continue; }
                    $absPath = "$path/$e";
                    if (is_dir($absPath)) {
                        // check $maxDepth first before entering next recursion
                        if ($maxDepth != 0) {
                            // reduce maximum depth for next iteration
                            $this->iterate($absPath, $maxDepth - 1);
                        }
                    } else {
                        // regular file found, call the found handler
                        call_user_func_array($this->onFound, array($absPath));
                    }
                }
                closedir($d);
            }
        
            // helper function to instantiate one finder object
            // return value is not very important though, because all methods are private
            public static function find($path, $onFound, $maxDepth = 0)
            {
                return new self($path, $onFound, $maxDepth);
            }
        }
        
        // start finding files (maximum depth is one folder down) 
        $count = $bytes = 0;
        FileFinder::find('.', function($file) use (&$count, &$bytes) {
            // the closure updates count and bytes so far
            ++$count;
            $bytes += filesize($file);
        }, 1);
        
        echo "Nr files: $count; bytes used: $bytes\n";
        

        您传递基本路径、找到的处理程序和最大目录深度(-1 禁用)。找到的处理程序是您在外部定义的函数,它从find() 函数中给定的路径中传递相对路径名。

        希望它有意义并且对你有帮助:)

        【讨论】:

          【解决方案5】:

          您可以使用RecursiveDirectoryIterator 这样做

          <?php
          function scan_dir($path){
              $ite=new RecursiveDirectoryIterator($path);
          
              $bytestotal=0;
              $nbfiles=0;
              foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) {
                  $filesize=$cur->getSize();
                  $bytestotal+=$filesize;
                  $nbfiles++;
                  $files[] = $filename;
              }
          
              $bytestotal=number_format($bytestotal);
          
              return array('total_files'=>$nbfiles,'total_size'=>$bytestotal,'files'=>$files);
          }
          
          $files = scan_dir('./');
          
          echo "Total: {$files['total_files']} files, {$files['total_size']} bytes\n";
          //Total: 1195 files, 357,374,878 bytes 
          ?>
          

          【讨论】:

          • @Neoweiter 这也扫描子目录,我以为你只想要子目录级别?
          • @jack,我不会使用 sub sub dirs,但如果脚本查找它就不是那么重要 ;)
          • 您可以使用RecursiveIteratorIterator 上的setMaxDepth() 方法来限制递归的深度:这里您可能希望将其设置为1(即一个子目录深度)。
          • 它包括隐藏的快捷链接,如双点..和点。
          • 可以为is_dir()加点东西,这样目录就不会被计入文件了。:)
          【解决方案6】:

          每个循环的 A 可以更快地完成任务 ;-)

          我记得,opendir 派生自 SplFileObject 类,它是一个 RecursiveIterator 、 Traversable 、 Iterator 、 SeekableIterator 类,因此,如果您使用 SPL 标准 PHP 库来检索整个图像计数,则不需要 while 循环甚至在子目录中。

          但是,我有一段时间没有使用 PHP,所以我可能会犯错误。

          【讨论】:

            猜你喜欢
            • 2015-06-28
            • 2015-06-27
            • 2015-06-15
            • 2018-08-07
            • 2016-09-04
            • 1970-01-01
            • 1970-01-01
            • 2011-02-19
            • 2016-05-16
            相关资源
            最近更新 更多