0

我得到了一个路径数组(结合了默认和用户设置),需要对一些数据文件执行递归搜索,这些数据文件可以隐藏在任何这些路径中的数万个文件之间。

我用 a 进行递归搜索,RecursiveDirectoryIterator但速度很慢,建议的替代exec("find")方法甚至更慢。为了节省时间、I/O 和处理能力,我想预先进行一些预处理以避免多次搜索目录树并计算给定路径的最小公分母。我将不胜感激有关如何执行此操作的任何建议。

问题是,任何给定的路径可能不仅是其他路径的祖先,或者只是相互符号链接,而且可能作为真实路径或符号链接的路径给出。至少有人可能会假设不会有任何循环符号链接(尽管检查不会是坏事)。

我需要在 PHP 中实现它,并且我草拟了以下代码,它还没有涵盖所有情况。

// make all given paths absolute and resolve symlinks
$search_paths = array_map( function($path) {
    return realpath( $path ) ?: $path;
}, $search_paths );

// remove all double entries
$search_paths = array_unique( $search_paths );

// sort by length of path, shortest first
usort($search_paths, function($a, $b) {
    return strlen($a) - strlen($b);
});

// iterate over all paths but the last
for ( $i = 0; $i < count( $search_paths ) - 1; $i++ ) {
    // iterate over all paths following the current
    for ( $j = $i; $j < count( $search_paths ); $j++ ) {
        if ( strpos ( $search_paths[$j], $search_paths[$i] ) === 0 ) {
            // longer path starts with shorter one, thus it's a child. Nuke it!
            unset( $search_paths[$j] );
        }
    }
}

这段代码的不足之处:想象一下这些路径$search_paths

/e/f
/a/b/c/d
/e/f/g/d

作为 .的/e/f/g/d符号链接/a/b/c/d

上面的代码将留下这两个:

/e/f
/a/b/c/d

但搜索/e/f实际上就足够了,因为它/a/b/c/d通过 symlink覆盖/e/f/g/d。这听起来像是一个边缘案例,但实际上在我的情况下很有可能。

棘手,是吗?

我很确定我不是唯一一个遇到这个问题的人,但我无法使用谷歌找到解决方案。也许我只是没有得到正确的措辞来解决这个问题。

感谢您阅读到这里!:)

4

0 回答 0