2011-03-02 106 views
7

我必須做一個函數,列出所有子文件夾到一個文件夾中。我有一個無文件過濾器,但該函數使用scandir()進行列表。這使得應用程序非常慢。有沒有其他的scandir(),甚至不是原生的php函數? 在此先感謝!PHP:scandir()太慢

+3

你正在掃描的目錄中有多少文件/目錄?它不應該這麼慢,除非你在每個目錄上執行一個'stat()',否則就有數千個文件。 –

+0

http://www.php.net/manual/en/function.scandir.php#96326 – Detect

+0

http://www.php.net/manual/en/function.scandir.php#73062 – Detect

回答

2

您可以使用READDIR這可能會更快,這樣的事情:

function readDirectory($Directory,$Recursive = true) 
{ 
    if(is_dir($Directory) === false) 
    { 
     return false; 
    } 

    try 
    { 
     $Resource = opendir($Directory); 
     $Found = array(); 

     while(false !== ($Item = readdir($Resource))) 
     { 
      if($Item == "." || $Item == "..") 
      { 
       continue; 
      } 

      if($Recursive === true && is_dir($Item)) 
      { 
       $Found[] = readDirectory($Directory . $Item); 
      }else 
      { 
       $Found[] = $Directory . $Item; 
      } 
     } 
    }catch(Exception $e) 
    { 
     return false; 
    } 

    return $Found; 
} 

可能需要一些tweeking,但是這基本上是SCANDIR做什麼,它應該是更快的,如果不是請更新爲我想看看我能否做出更快的解決方案。

另一個問題是,如果你閱讀一個非常大的目錄,你可以在內部存儲器中填充一個數組,並且這可能是你的內存正在發生的地方。

您可以嘗試創建一個讀取偏移量的函數,以便一次返回50個文件!同時文件的

閱讀塊將是一種簡單易用,會像這樣:

$offset = 0; 
while(false !== ($Batch = ReadFilesByOffset("/tmp",$offset))) 
{ 
    //Use $batch here which contains 50 or less files! 

    //Increment the offset: 
    $offset += 50; 
} 
+0

一切似乎都很完美,但如何禁用此功能。和..文件夾。我也有一個空的索引,我不想列出。我想它是在catch(Exception)中,但是如何格式化它? –

+0

我已更新,所以它不包含'.'或'..',但我不知道你的意思是關於空索引 – RobertPitt

+0

是的!它對我來說非常合適。感謝你們! –

2

不要寫你自己的。 PHP具有遞歸目錄迭代器專門建了這一點:

http://php.net/manual/en/class.recursivedirectoryiterator.php

根據經驗,因爲它在直C'S實現,任何你在PHP建立一個規則(又名不是100%的時間)要要慢一些。

+1

除非你正在編寫實時軟件,否則php的「緩慢」根本無關 – dynamic

+0

將目錄迭代器包裝在一個'ParentIterator'(或定製的迭代器過濾器)和bam中,沒有文件。 – salathe