Si vous traversez récursivement une arborescence de répertoire par la méthode évidente, vous rencontrez des problèmes avec une récursion infinie lorsqu'un lien symbolique pointe vers un répertoire parent. P>
Une solution évidente serait de vérifier simplement des liens symboliques et de ne pas les suivre du tout. Mais cela pourrait être une surprise désagréable pour un utilisateur qui ne s'attend pas à ce qui se comporte à d'autres fins, comme un répertoire parfaitement normal d'être ignoré silencieusement. P>
Une solution alternative peut être de garder une table de hachage de tous les annuaires visités jusqu'à présent et d'utiliser ceci pour vérifier les boucles. Mais cela nécessiterait qu'il y aurait une représentation canonique, d'une manière à obtenir l'identité, de l'annuaire que vous examinez actuellement (quel que soit le chemin que vous avez atteint). P>
Les utilisateurs UNIX seraient généralement généralement la deuxième solution comme moins surprenante? P>
Si tel est-ce, est-il un moyen d'obtenir une telle représentation / identité canonique d'un répertoire, qui est portable sur des systèmes UNIX? (J'aimerais que cela fonctionne à travers Linux, BSD, Mac OS, Solaris, etc. Je m'attends à avoir à écrire du code séparé pour Windows.) P>
6 Réponses :
Puisque vous n'avez pas spécifié quelle langue vous travaillez avec (le cas échéant), nous allons commencer avec le shell: si vous êtes sur un système GNU Si vous êtes sur un Mac (qui a un non-gnu L'autre option consiste à utiliser des ID d'inode pour suivre des fichiers uniques (via Alternativement, de nombreuses langues de programmation ont des liaisons à la fonction POSIX Si vous travaillez déjà dans une langue qui a une telle fonction, l'utilisation est fortement recommandée, car vous obtiendrez souvent une compatibilité multiplate-forme gratuitement (en supposant que votre langue est multiplate-forme). P> readlink code>, utilisez simplement le code < > readlink -f
readlink code> qui se comporte différemment), voir Comment puis-je obtenir le comportement de GNU's Readlink -F sur un Mac? pour le chemin d'accomplissement même tâche. p>
stat code> ou similaire), mais cela nécessitera d'abord tous les symboles de toute façon (puisque les symboles eux-mêmes ont leur propre unique. ID INODE), et le moyen le plus simple de suivre tous les symboles de symboles est, eh bien,
readlink code>. p>
REALPATH CODE>, qui effectue essentiellement la même fonction que
readlink -f code> (mais comme un appel de bibliothèque). Par exemple, Python a
OS.PATH.REALPATH ( ) code>
, C a comme fonction de stdlib.h code>, et cetera. p>
Le chemin absolu de l'annuaire est une telle représentation. Vous pouvez l'obtenir avec la fonction realpath code>, qui est définie dans la norme POSIX, de sorte qu'il fonctionnera sur n'importe quel système compatible POSIX. Voir
Man 3 RealPath code>. P>
Non seulement les symboles, mais aussi des liens matériels aussi. Pas très commun, mais pas interdit. (Seule les répertoires de la racine peuvent La seule chose qui est canonique est {Nombre de périphériques, inode_number}. Mais les systèmes de fichiers réseau peuvent mal se conduire mal. P>
Ce problème de fichiers identiques doit être résolu par de nombreuses applications, par exemple un vérificateur pour les doublées de fichier (contenus indiciels, noms différents) et utilitaires agissant sur des hiérarchies de l'ensemble du répertoire, telles que Une bonne implémentation ne voudrait pas donner de faux positifs pour des fichiers liés durs et des fichiers symboliques, soit par le biais de symboles aux répertoires parentes, soit à des fichiers. P>
L'approche la plus portable pour résoudre est d'identifier des fichiers en regardant les fonctions STAT / FSTAT POSIX et la statistique goudron p >
structure CODE> Ils remplissent avec
st_dev code> et
st_ino code> membres.
Une mise en œuvre réelle mondiale d'un fichier de dape de fichier en C Utilisation de cette stratégie est Samefile (une implémentation différente de laquelle Était une entrée gagnante du 1998 IOCCC : -) P>
L'API la plus fréquemment ignorée dans ce champ serait
NFTW a des options pour éviter de passer des symboles traversants. Il a des capacités beaucoup plus avancées que cela. Voici un échantillon simple de la page d'homme elle-même: p> Voir aussi p>
La page d'homme pour NFTW dit d'utiliser les fonctions code> FTS code> à la place, qui sont également disponibles sur Linux et BSD (MacOS) et fonctionnent plus efficacement. Voir aussi ma réponse ci-dessous (qui ne fournit pas plus d'informations, cependant)
Merci @thomastempelmann pour avoir ajouté de la perspective. Je n'utilise jamais réellement cette fonction dans la pratique (je suppose que je pourrais dans un programme "rapide" qui devait être dans C. J'ai fait une fois une question d'entretien avec elle :)). Il est bon de relire les pages d'homme lors de la réutilisation des extraits après 10 ans!
Il y a aussi la fonction Linux / BSD Il vous donne un itérateur facile à utiliser pour parcourir tous les contenus de sous-répertoires tout en détectant de telles récursions symboliques. P>
En fait, la page man (sur MacOS) pour Ces fonctions sont fournies pour la compatibilité avec le code hérité. Le nouveau code doit utiliser les fonctions FTS (3). P>
blockQuote> FTS_OPEN () CODE>. P>
NFTW code> dit que c'est une ancienne fonction qui est maintenant remplacée par l'API FTS que je mentionne ici: P>