0

一連のパス (デフォルト設定とユーザー設定を組み合わせたもの) を取得し、これらのパスのいずれかに含まれる何万ものファイルの間に隠されているデータ ファイルを再帰的に検索する必要があります。

a を使用して再帰検索を行いますが、RecursiveDirectoryIterator非常に遅く、推奨される代替手段exec("find")はさらに遅くなります。時間、I/O、および処理能力を節約するために、事前に前処理を行って、ディレクトリ ツリーを複数回検索することを避け、指定されたパスの最小公分母を計算したいと考えています。これを行う方法についてアドバイスをいただければ幸いです。

問題は、指定されたパスのいずれかが、他のパスの祖先であるか、単に相互にシンボリック リンクされているだけでなく、実際のパスまたはシンボリック リンクへのパスとして指定されている可能性があることです。循環するシンボリック リンクが存在しないと想定する人が少なくとも 1 人いるかもしれません (ただし、チェックは悪くありません)。

これを 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です。

上記のコードでは、次の 2 つが残ります。

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

しかし、シンボリックリンクを介してカバーしているため、実際には検索/e/fで十分です。これは特殊なケースのように聞こえるかもしれませんが、実際には私の状況ではかなり可能性があります。/a/b/c/d/e/f/g/d

トリッキーですね。

この問題を抱えているのは私だけではないと確信していますが、Googleを使用して解決策を見つけることができませんでした. 多分私は問題の正しい言葉遣いを理解していないだけです。

ここまで読んでくれてありがとう!:)

4

0 に答える 0