在PHP中使用array_pop + yield实现读取超大型目录功能示例
php  /  管理员 发布于 7个月前   346
在php中需要读取处理一个超大型目录,该单目录有200G大小;
一般常规做法是:
使用递归实现,不过读取到的路径数组非常大,配置不行的机器分分钟内存溢出.
看看常规递归实现代码:
function recursiveScan($dir) {
$files = [];
$items = scandir($dir);
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
$files = array_merge($files, recursiveScan($path)); // 递归读取子目录
} else {
$files[] = $path;
}
}
return $files;
}
$directory = '/path/to/directory';
$files = recursiveScan($directory);
foreach ($files as $file) {
echo $file . PHP_EOL;
}
以上是很常见的做法,读取小文件夹没问题,但是大文件夹会超出内存
优化解决思路:
1、在这个优化后的函数中,我们将 traverseFolder 函数改为生成器函数,并使用 yield $path;
逐步生成文件路径。
这样在调用这个函数时,可以逐步处理文件而不是一次性返回所有文件路径。
这种方式可以减少内存占用,并在需要时逐个获取文件路径。
2、不使用递归这种耗资源的方式, 使用 array_pop 栈的思路来模拟迭代
改进过的方法如下,非常的节省内存,
默认 128m 的配置即可读取超大目录:
优化示例代码:
function traverseFolder($folder) {
$stack = [$folder]; // 使用栈来模拟迭代
$ext_map = $this->config('ext_map');
$ext_map_arr = explode("\n", $ext_map);
while (!empty($stack)) {
$currentFolder = array_pop($stack);
$handle = opendir($currentFolder);
while (($file = readdir($handle)) !== false) {
if ($file != '.' && $file != '..') {
$path = $currentFolder . '/' . $file;
if (is_dir($path)) {
$stack[] = $path;
} else {
yield $path; // 生成器函数逐步生成文件路径
}
}
}
closedir($handle);
}
}
调用示例:
使用就直接用foreach循环上面的结果, 返回$path即可;
这样就可以轻松读取 200G 甚至 2T 的文件夹了.
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号