$user = 'root';$pass = 'thrope';$dbh = new PDO('mysql:host=localhost;dbname=income', $user, $pass);$query = 'insert into picinfo set picpath=:pp, picsize=:ps';//把檔案路徑和檔案大小寫入資料庫$stmt = $dbh->prepare($query);function dir_read($dir){$dh = opendir($dir);//if (is_dir($dir)) echo realpath($dir).'
';while (false !== ($filename = readdir($dh))){//echo realpath($dir.'/'.$filename).'
';//if ($filename == '.' || $filename == '..') continue;if (is_file($dir.'/'.$filename)){global $stmt;$stmt->execute(array(':pp'=>realpath($dir.'/'.$filename), ':ps'=>filesize(realpath($dir.'/'.$filename))));//echo $dbh->errorCode();}if (is_dir(realpath($dir.'/'.$filename)))//這個遞迴調用特別耗費資源dir_read(realpath($dir.'/'.$filename));}closedir($dh);}dir_read('K:/project/fileOperate');
上面的代碼主要功能是把K:/project/fileOperate這個目錄下所有的檔案和子檔案夾下所有的檔案名稱和檔案大小寫入資料庫中,但是這個遞迴太耗費資源了,佔用了超過1G記憶體
我想請教是我什麼地方做得有問題?或者有更好的方法?
回複討論(解決方案)
之前xu版主的一個方法在這裡借用一下
$dir='d:\\';
$res=glob($dir);
for($i=0;$i if(is_dir($res[$i])){
$res=array_merge($res,glob($res[$i].'/*'));
$g=glob($res[$i].'/*');
var_dump($g);
}
}
?>
你 為什麼把 if ($filename == '.' || $filename == '..') continue; 注釋掉?
當 $filename = '.' 和 $filename = '..' 時,is_dir(realpath($dir.'/'.$filename) 成立,不就產生死迴圈了嗎?
其實用 glob 函數 或 目錄迭代器要簡單的多
這邊遞迴耗記憶體應該是mysql的insert操作耗記憶體比較嚴重, 可以考慮使用load data infile 這種方式最佳化一下。。
if ($filename == '.' || $filename == '..') continue; ?句是必?有的,否??死循?。
用PHP內建的SPL庫處理會快很多:例如
$iterator = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator('./'));
foreach ($iterator as $it){
echo $it->getFilename(),'->',$it->getSize(),'
';
}
可以自己參考下手冊,SPL還是封裝的蠻好的
memory_get_peak_usage
我用這個函數分別測試了空指令碼和你的代碼運行於一個全是零碎檔案的8.4G的D盤,結果相差無幾
有點搞不懂了
1G也太恐怖了吧,樓主還是想想別的辦法吧
感覺LZ的代碼有問題哇 應該把那個判斷是不是當前和上級目錄的加進來,這個樣子應該就不會有那麼大的記憶體佔用了
if ($filename == '.' || $filename == '..') continue;
這個要加上。