gpt4 book ai didi

php - 使用 FilesystemIterator 将尾部斜杠应用于文件夹

转载 作者:行者123 更新时间:2023-12-02 05:26:38 24 4
gpt4 key购买 nike

使用以下代码段递归映射当前目录的内容:

$files = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator('./',
FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS),
RecursiveIteratorIterator::SELF_FIRST
);

$files = array_values(array_map('strval', iterator_to_array($files)));

返回这样的东西:

Array
(
[0] => ./1.png
[1] => ./a.php
[2] => ./adminer
[3] => ./adminer/adminer.css
[4] => ./adminer/adminer.php
)

有什么办法可以得到RecursiveDirectoryIterator/FilesystemIterator模拟 glob() 中存在的 GLOB_MARK 行为功能?来自手册:

GLOB_MARK - Adds a slash to each directory returned.

我知道我可以通过简单地这样做来模仿它:

foreach ($files as $key => $value)
{
$files[$key] .= (is_dir($value) ? '/' : '');
}

但这需要(不必要的?)多次访问磁盘。我正在寻找一种快速确定路径是目录还是常规文件的方法,结尾斜线似乎是理想的解决方案。

我计划用它遍历数万(如果不是数百)个文件,因此性能至关重要。

奖励问题:有什么方法可以只获取目录(递归)?

最佳答案

您可以创建自己的 GlobMarkIterator 优点:

  • 将结束斜线返回到目录,就像 GLOB_MARK
  • 不需要使用 array_mapstrval 将其转换为字符串
  • 没有额外的 foreach 循环与 is_dir
  • 仍然和原来一样快
  • 是的,我知道我作弊了

例子

$ri = new RecursiveIteratorIterator(new GlobMarkIterator('./', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS), RecursiveIteratorIterator::SELF_FIRST);
$files = array_values(iterator_to_array($ri));

echo "<pre>";
print_r($files);

输出

Array
(
[0] => ./test/backups/ <----------- Note ending slash
[1] => ./test/CSV/
[2] => ./test/CSV/abc.csv
[3] => ./test/final/
[4] => ./test/thumb/
[5] => ./test/thumb/a.png
[6] => ./test/thumb/s.svg
[7] => ./test/thumb/sample.svg
)



奖励问题:有什么方法可以只获取目录(递归)?

这应该是另一个问题,但都一样......我希望你不要对此感到满意并悬赏

解决方案:

$ri = new RecursiveIteratorIterator( new GlobMarkDirectory('./test'), RecursiveIteratorIterator::SELF_FIRST);
$dir = array_values(iterator_to_array($ri));

echo "<pre>";
print_r($dir);

输出

Array
(
[0] => ./test/backups/
[1] => ./test/CSV/
[2] => ./test/final/
[3] => ./test/thumb/
)

使用的类

GlobMarkIterator

class GlobMarkIterator extends RecursiveDirectoryIterator {
function current() {
return $this->isDir() ? $this->getPathname() . "/" : $this->getPathname();
}
}

GlobMarkDirectory

class GlobMarkDirectory  extends RecursiveFilterIterator {
public function __construct($path) {
parent::__construct(new GlobMarkIterator($path, FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS));
}
public function accept() {
return $this->getInnerIterator()->isDir();
}
public function getChildren() {
return new GlobMarkDirectory($this->getInnerIterator()->getPathname());
}
}



编辑 .. 如果您不关心 empty dir 并且由于速度和开销您不想使用 isDir 这里是另一种解决方案

解决方案

$ri = new RecursiveIteratorIterator(new GlobMarkFastDirectory  (__DIR__), RecursiveIteratorIterator::SELF_FIRST);
$dir = array_values(array_unique(iterator_to_array($ri)));

GlobMarkFastDirectory

class GlobMarkFastDirectory  extends RecursiveDirectoryIterator {
function current() {
return dirname($this->getPathname()) ."/";
}
}

关于php - 使用 FilesystemIterator 将尾部斜杠应用于文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12988204/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com