web-dev-qa-db-fra.com

Java 1.6 - déterminer les liens symboliques

Dans une classe DirectoryWalker, je veux savoir si une instance de File est en fait un lien symbolique vers un répertoire (en supposant que le marcheur marche sur des systèmes UNIX). Étant donné que je sais déjà que l'instance est un répertoire, la condition suivante serait-elle fiable pour déterminer le lien symbolique?

File file;
// ...      
if (file.getAbsolutePath().equals(file.getCanonicalPath())) {
    // real directory ---> do normal stuff      
}
else {
    // possible symbolic link ---> do link stuff
}
43
msi

La technique utilisée dans Apache Commons utilise le chemin canonique vers le répertoire parent, pas le fichier lui-même. Je ne pense pas que vous puissiez garantir qu'un décalage est dû à un lien symbolique, mais c'est une bonne indication que le fichier a besoin d'un traitement spécial.

Ceci est code Apache (sous réserve de leur licence ), modifié pour des raisons de compacité.

public static boolean isSymlink(File file) throws IOException {
  if (file == null)
    throw new NullPointerException("File must not be null");
  File Canon;
  if (file.getParent() == null) {
    Canon = file;
  } else {
    File canonDir = file.getParentFile().getCanonicalFile();
    Canon = new File(canonDir, file.getName());
  }
  return !Canon.getCanonicalFile().equals(Canon.getAbsoluteFile());
}
45
erickson

Faites également attention à file.isFile() et file.isDirectory() qui renvoient tous les deux des résultats basés sur le fichier résolu et donc retournent tous les deux false lorsque file fait référence à un lien symbolique où la cible n'existe pas.

(Je sais que ce n'est pas une réponse utile en soi, mais cela m'a fait trébucher plusieurs fois, alors j'ai pensé que je devrais partager)

13
Rob Oxspring

Java 1.6 ne fournit pas un tel accès de bas niveau au système de fichiers. On dirait NIO 2 , qui devrait être inclus dans Java 1.7, prendra en charge les liens symboliques. n brouillon de la nouvelle API est disponibles. Liens symboliques sont mentionnés ici , création et suivi eux est possible. Je ne sais pas exactement quelle méthode doit être utilisée pour trouver pour savoir si un fichier est un lien symbolique. Il y a ne liste de diffusion pour discuter de NIO 2 - peut-être qu'ils le sauront.

13
Esko Luontola

Il semble que getCanonicalPath() puisse faire d'autres choses qui pourraient le rendre différent du chemin absolu.

Cette méthode convertit d'abord ce nom de chemin en forme absolue si nécessaire, comme en appelant la méthode getAbsolutePath (), puis le mappe à sa forme unique en fonction du système. Cela implique généralement la suppression de noms redondants tels que "." et ".." à partir du chemin d'accès, résolvant les liens symboliques (sur les plates-formes UNIX) et convertissant les lettres de lecteur en cas standard (sur les plates-formes Microsoft Windows).

Mais cela pourrait fonctionner pour la grande majorité de vos cas d'utilisation; Votre kilométrage peut varier.

5
Michael Myers

Si vous codez déjà quelque chose spécifiquement pour * nix, vous pouvez exécuter une commande Shell à partir de Java comme ceci:

Process p = Runtime.getRuntime().exec(new String[]{"test", "-h", yourFileName});
p.waitFor();
if (p.exitValue() == 0) 
   System.out.println("This file is a symbolic link");
else
   System.out.println("This file is not a symbolic link");

C'est très spécifique à * nix, mais cela fonctionne au moins.

3
Beaker

Désolé de répondre à un si vieux message, mais je cherchais une solution pour les systèmes Windows il y a quelque temps, et certaines des réponses précédentes n'ont pas fonctionné pour moi. Si vous n'êtes pas concerné par la compatibilité multiplateforme et n'avez besoin que d'une solution pour Windows, la technique suivante a bien fonctionné pour mes besoins.

File f = new File("whatever file or folder");
if (f instanceof ShellFolder) {
  ShellFolder sf = (ShellFolder)f;
  if (sf.isLink()) {
    // Your code when it's a link
  }
}
1
Ray Newman